Swift protocol for string interpolation

前端 未结 3 949
时光取名叫无心
时光取名叫无心 2021-02-20 00:19

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 somet

相关标签:
3条回答
  • 2021-02-20 00:45

    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

    0 讨论(0)
  • 2021-02-20 00:48

    In Swift 5 Apple introduced Custom String Interpolation.

    Suppose you have person struct with two properties name and age.

    struct Person {
      var name: String
      var age: Int
    } 
    

    If you wanted to add a special string interpolation for that so that we can print persons in descriptive way, we can add an extension to String.StringInterpolation with a new appendInterpolation() method.

     extension String.StringInterpolation {
           mutating func appendInterpolation(_ person: Person) {
           appendInterpolation("My name is \(person.name) and I'm \(person.age) years old.")
        }
    }
    

    Now If we print the person details like:

     let person = Person(name: "Yogendra", age: 28)
     print("Person Details: \(person)")
    

    Output will be:

    Person Details: My name is Yogendra and I'm 28 years old.
    
    0 讨论(0)
  • 2021-02-20 00:55

    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.

    0 讨论(0)
提交回复
热议问题