orkoden orkoden - 3 months ago 9
Swift Question

Why does String.append not work for formatted strings like "foo\(bar)"?

While implementing

CustomStringConvertible
I encountered an error I don't quite understand.

struct Name {
let name: String?
}

extension Name: CustomStringConvertible {
var description: String {
var desc = ""
if let name = name {
desc.append("Page: \(name)")
}
return desc
}
}


This leads to the following errors:

error: cannot invoke 'append' with an argument list of type '(String)'
note: overloads for 'append' exist with these partially matching parameter lists: (UnicodeScalar), (Character)


It looks like the compiler doesn't know which implementation of the
append
function to use.

Changing it to

desc.append(name)


works fine. As does

desc.appendContentsOf("Page: \(name)")


Why is that exactly?

Answer

In Swift 2, String has two append methods, which take a single character or Unicode scalar as an argument:

public mutating func append(c: Character)
public mutating func append(x: UnicodeScalar)

That's why desc.append("Page: \(name)") does not compile (and desc.append(name) does not compile either). But

public mutating func appendContentsOf(other: String)

appends another string. Alternatively use

desc += "Page: \(name)"

In Swift 3, those methods have been renamed to

public mutating func append(_ other: Character)
public mutating func append(_ other: UnicodeScalar)
public mutating func append(_ other: String)

and then it is

desc.append("Page: \(name)")