Jak mogę zmienić reprezentację tekstową wyświetlaną dla typu w języku Swift?


92

Jak mogę zmodyfikować tekstowe dane wyjściowe, które są wyświetlane w interpolacji ciągów?

PrintableProtokół wygląda najbardziej oczywiste, ale to zignorował zarówno String interpolacji podczas drukowania instancji, np:

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

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

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

Podobnie toString()konwencja nie ma żadnego skutku:

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)

Zachowanie jest znowu inne w PlayGround, który używa własnej reprezentacji String dla struktur, tj .:

p // {x 10, y 20}

Czy istnieje sposób, aby zmienić sposób wyświetlania instancji?


Powyższy kod działa zgodnie z oczekiwaniami w Playgrounds w Xcode 6.3 beta 4
carbo18

Odpowiedzi:


113

Swift 2-4

Podsumowanie

Zgodność z CustomStringConvertibleprotokołem i dodaj description:

var description: String {
    return "description here"
}

Przykład

Możesz stworzyć kilka struktur:

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)."
    }
}

Jeśli je zainicjujesz:

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])

Niestandardowe opisy pojawią się na Twoim placu zabaw:

wprowadź opis obrazu tutaj

Zobacz także CustomDebugStringConvertible, których możesz użyć, aby uzyskać bardziej szczegółowe dane wyjściowe podczas debugowania.


Uwaga dotycząca użytkowania

Możesz zainicjować Stringdowolny typ bez implementowania tego protokołu. Na przykład:

wprowadź opis obrazu tutaj

Z tego powodu doktorzy mówią:

Dlatego odradza się używanie CustomStringConvertiblejako ograniczenia ogólnego lub bezpośredniego dostępu do zgodnego typu description.


37

Odpowiednie dokumenty Apple Swift

Apple podaje następujący przykład:

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

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

Jeśli spróbujesz tego na placu zabaw, pojawi się ten sam problem, który otrzymujesz ( V11lldb_expr...). Na placu zabaw opis po prawej stronie pojawia się, gdy wywołujesz inicjator, ale printlnnie zwraca on czegoś czytelnego.

Jednak poza placem zabaw ten kod zachowuje się zgodnie z oczekiwaniami. Zarówno twój kod, jak i przykładowy kod z Apple powyżej wypisują poprawne, descriptiongdy są używane w kontekście innym niż plac zabaw.

Myślę, że nie można zmienić tego zachowania na placu zabaw. Może to być po prostu błąd.

EDYCJA : Jestem prawie pewien, że to błąd; Wysłałem raport o błędzie do Apple.

AKTUALIZACJA : W Swift 2 zamiast Printableużywać CustomStringConvertible( odpowiedni link do dokumentu ).

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

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


1

Alternatywnie w Swift 5+ możesz rozszerzyć String.StringInterpolation

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

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

Spowoduje to zmianę wartości dla, print("\(p)") ale nie dla print(p)- co nadal będzie używać opisu


0

Jeśli otworzysz widok konsoli: View -> Assistant Editor -> Show Assistant Editor, zobaczysz oczekiwane wydrukowane linie Sprawdzone w xCode 6.3.2 z Yosimite 10.10

wprowadź opis obrazu tutaj


0

AppCodezapewnia a Generate| debugDescriptioni `` Generuj | opis ". Lepiej niż wpisywanie ich w strukturze z wieloma członkami.

wprowadź opis obrazu tutaj

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.