What protocol do I have to implement to control the way an object is represented within a string interpolation in Swift?
I wan't to specify what get's printed in something like this:
struct A{
}
var a = A()
println("\(a)")
What protocol do I have to implement to control the way an object is represented within a string interpolation in Swift?
I wan't to specify what get's printed in something like this:
struct A{
}
var a = A()
println("\(a)")
You need to implement the Printable
protocol:
This protocol should be adopted by types that wish to customize their textual representation. This textual representation is used when objects are written to an
OutputStreamType
.
protocol Printable {
var description: String { get }
}
There's also the DebugPrintable
protocol when it's only for debugging purposes:
This protocol should be adopted by types that wish to customize their textual representation used for debugging purposes. This textual representation is used when objects are written to an
OutputStreamType
.
protocol DebugPrintable {
var debugDescription: String { get }
}
Documentation (Thanks @MartinR)
Note: As @Antonio and @MartinR mentioned in the comments, this doesn't work in the playground (as of Xcode6 GM anyway); that's a known bug. It does work in compiled apps.
From the Xcode6 GM Release Notes:
In Playgrounds, println() ignores the Printable conformance of user-defined types. (16562388)
As of Swift 2.0 Printable
has now become CustomStringConvertible
. Everything stays the same as before, you still need to implement
var description: String { get }
But now its called CustomStringConvertible. And debug is CustomDebugStringConvertible
I would like to put an alternative solution here:
The protocol for string interpolation in Swift is StringInterpolationConvertible
. That is, any class which implements the protocol, can be constructed from a string interpolation.
Back to the question, to control what is printed out for a String string interpolation of instances of class A
, you would need to create a String extension and overload the init(stringInterpolationSegment expr: A)
function.
extension String {
init(stringInterpolationSegment expr: A) {
//do custom work here
//for example: self.init(expr.description)
}
}
In case you are looking for a way to remove the annoying "Optional(...)" when interpolating Optional variables, which I think is the main reason why people would want to control how an object gets printed out, just have a look at the pod NoOptionalInterpolation here.
Additional information (edited):
Confirm that overriding description
will only work for your own struct/class, but not for existing struct/class such as Int
and Optional
.