1

Apple's documentation and many articles suggest you can convert a substring (string.subsequence) to a string just by calling String(substring)and in fact this works.

let str = "Hello world"
let hello = str.prefix(5) //create substr
//CREATE STRING FROM SUBSTRING
let hellostr = String(hello) //works

However when the substring is an optional as in the following,

 let str = Optional("Hello world")
 let hello = str?.prefix(5) //create substr
 //CREATE STRING FROM OPTIONAL SUBSTRING
 let hellostr = String(hello) //gives error 

I am getting the error

"No exact matches in call to initializer "

What could be causing this error?

Thanks for any suggestions.

2
  • 1
    The method is init(_ substring: Substring), not init(_ substring: Substring?). So String(hello ?? Substring()) should do the trick. Also the comments about the code " //gives error " is false and misleading (I guess wrong copy/paste) Commented Jul 5, 2024 at 11:51
  • What is the goal to create a string from nil? Practically there is none therefore an init method is pointless. Commented Jul 5, 2024 at 11:59

1 Answer 1

4

You need to unwrap the Optional Substring as you cannot directly create a String from an Optional Substring.

You need to decide how you want to handle nil values for hello and based on that, choose the appropriate option.

Here's a few options:

  1. Use Optional.map to create a non-optional String from the Substring in case the optional had a non-nil value and if the optional was nil, assign nil to the result/

    // hellostr will be nil if hello was nil, otherwise it will have a value
    // The type of hellostr is Optional<String>
    let hellostr = hello.map(String.init)
    
  2. If you always want hellostr to have a value, you need to provide a default value either to the return value of Optional.map

    let hellostr = hello.map(String.init) ?? ""
    

    or (as Martin R pointed out in comments) to the Optional<Substring> passed to String.init:

    let hellostr = String(hello ?? "")
    
  3. You can also use optional binding to replace Optional.map with more verbose syntax

    let hellostr: String
    if let hello = hello {
      hellostr = String(hello)
    } else {
      hellostr = ""
    }
    
Sign up to request clarification or add additional context in comments.

1 Comment

An alternative for #2 is let hellostr = String(hello ?? "")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.