swiftstringsubstringinitializer

Convert optional substring to string in Swift


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.


Solution

  • 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 = ""
      }