Jak mogę zmodyfikować tekstowe dane wyjściowe, które są wyświetlane w interpolacji ciągów?
Printable
Protokół 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?
Odpowiedzi:
Swift 2-4
Podsumowanie
Zgodność z
CustomStringConvertible
protokołem i dodajdescription
: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:
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ć
String
dowolny typ bez implementowania tego protokołu. Na przykład:Z tego powodu doktorzy mówią:
źródło
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, aleprintln
nie 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,
description
gdy 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
Printable
uż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"
źródło
Wygląda na to, że jest to błąd na placu zabaw. Jeśli faktycznie skompilujesz i uruchomisz program normalnie, wypisze:
(10, 20) (10, 20) (10, 20) (10, 20)
zgodnie z oczekiwaniami.
Powinieneś to zgłosić pod adresem https://bugreport.apple.com
źródło
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 dlaprint(p)
- co nadal będzie używać opisuźródło
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
źródło
AppCode
zapewnia aGenerate| debugDescription
i `` Generuj | opis ". Lepiej niż wpisywanie ich w strukturze z wieloma członkami.źródło