Wie kann ich die Textdarstellung ändern, die für einen Typ in Swift angezeigt wird?

91

Wie kann ich die Textausgabe ändern, die bei der Zeichenfolgeninterpolation angezeigt wird?

Das PrintableProtokoll sieht am offensichtlichsten aus, wird jedoch sowohl bei der Zeichenfolgeninterpolation als auch beim Drucken der Instanz ignoriert, z.

struct Point : Printable
{
    var x = 0
    var y = 0

    var description : String {
        return "(\(x), \(y))"
    }

    func toString() -> String {
        return description
    }
}

Ebenso hat die toString()Konvention auch keine Wirkung:

var p = Point(x: 10, y: 20)

println(p)                   // V11lldb_expr_05Point (has 2 children)
println("\(p)")              // V11lldb_expr_05Point (has 2 children)
println(p.description)       // (10, 20)
println("\(p.description)")  // (10, 20)

Das Verhalten ist in PlayGround wieder anders, das eine eigene String-Darstellung für Strukturen verwendet, dh:

p // {x 10, y 20}

Gibt es eine Möglichkeit, die Anzeige einer Instanz zu ändern?

Mythos
quelle
Der obige Code funktioniert wie auf Playgrounds in Xcode 6.3 Beta 4
carbo18

Antworten:

112

Swift 2 - 4

Zusammenfassung

Passen Sie sich dem CustomStringConvertibleProtokoll an und fügen Sie hinzu description:

var description: String {
    return "description here"
}

Beispiel

Sie können einige Strukturen erstellen:

struct Animal : CustomStringConvertible {
    let type : String

    var description: String {
        return type
    }
}

struct Farm : CustomStringConvertible {
    let name : String
    let animals : [Animal]

    var description: String {
        return "\(name) is a \(self.dynamicType) with \(animals.count) animal(s)."
    }
}

Wenn Sie sie initialisieren:

let oldMajor = Animal(type: "Pig")
let boxer = Animal(type: "Horse")
let muriel = Animal(type: "Goat")

let orwellsFarm = Farm(name: "Animal Farm", animals: [oldMajor, boxer, muriel])

Die benutzerdefinierten Beschreibungen werden auf Ihrem Spielplatz angezeigt:

Geben Sie hier die Bildbeschreibung ein

Siehe auch CustomDebugStringConvertible, die Sie für eine ausführlichere Ausgabe während des Debuggens verwenden können.


Verwendungshinweis

Sie können a Stringvon jedem Typ aus initialisieren, ohne dieses Protokoll zu implementieren. Beispielsweise:

Geben Sie hier die Bildbeschreibung ein

Aus diesem Grund sagen die Dokumente:

Von der Verwendung CustomStringConvertibleals generische Einschränkung oder dem descriptiondirekten Zugriff auf konforme Typen wird daher abgeraten.

Aaron Brager
quelle
37

Relevante Apple Swift-Dokumente

Apple bietet dieses Beispiel:

struct MyType: Printable {
    var name = "Untitled"
    var description: String {
        return "MyType: \(name)"
    }
}

let value = MyType()
println("Created a \(value)")
// prints "Created a MyType: Untitled"

Wenn Sie dies auf dem Spielplatz versuchen, erhalten Sie das gleiche Problem wie bei ( V11lldb_expr...). Auf dem Spielplatz erhalten Sie die Beschreibung auf der rechten Seite, wenn Sie den Initialisierer aufrufen, aber der printlngibt nichts Lesbares zurück.

Außerhalb des Spielplatzes verhält sich dieser Code jedoch wie erwartet. Sowohl Ihr Code als auch der obige Beispielcode von Apple drucken den korrekten Code, descriptionwenn er in einem Kontext außerhalb des Spielplatzes verwendet wird.

Ich glaube nicht, dass Sie dieses Verhalten auf dem Spielplatz ändern können. Es könnte auch nur ein Fehler sein.

EDIT : Ich bin mir ziemlich sicher, dass dies ein Fehler ist; Ich habe einen Fehlerbericht an Apple gesendet.

UPDATE : PrintableVerwenden Sie in Swift 2 stattdessen CustomStringConvertible( relevanter Dokumentlink ).

struct MyType: CustomStringConvertible {
    var name = "Untitled"
    var description: String {
        return "MyType: \(name)"
    }
}

let value = MyType()
println("Created a \(value)")
// prints "Created a MyType: Untitled"
Cezary Wojcik
quelle
2

Dies scheint ein Fehler auf dem Spielplatz zu sein. Wenn Sie das Programm tatsächlich kompilieren und normal ausführen, wird Folgendes gedruckt:

(10, 20)
(10, 20)
(10, 20)
(10, 20)

wie erwartet.

Sie sollten dies unter https://bugreport.apple.com melden

Nicholas H.
quelle
0

Wenn Sie die Konsolenansicht öffnen: Ansicht -> Assistent-Editor -> Assistent-Editor anzeigen, werden die erwarteten Druckzeilen angezeigt, die in xCode 6.3.2 mit Yosimite 10.10 überprüft wurden

Geben Sie hier die Bildbeschreibung ein

Nikita Kurtin
quelle
0

Alternativ können Sie in Swift 5+ die String.StringInterpolation erweitern

struct Point {
    var x : Int
    var y : Int
}

extension String.StringInterpolation {
    mutating func appendInterpolation(_ value: Point) {
        appendInterpolation("\(value.x):\(value.y)")
    }
}

Dies ändert den Wert für, print("\(p)") aber nicht für print(p)- wobei die Beschreibung weiterhin verwendet wird

Ryan Heitner
quelle
0

AppCodebietet ein Generate| debugDescriptionund `` Generieren | Beschreibung`. Beats tippen sie für eine Struktur mit vielen Mitgliedern aus.

Geben Sie hier die Bildbeschreibung ein

Javadba
quelle