Как изменить текстовое представление, отображаемое для типа в Swift?
Как изменить текстовый вывод, который отображается в строковой интерполяции?
Протокол Printable
выглядит наиболее очевидным, но игнорируется как в String Interpolation, так и при печати экземпляра, например:
struct Point : Printable
{
var x = 0
var y = 0
var description : String {
return "(\(x), \(y))"
}
func toString() -> String {
return description
}
}
Аналогично, соглашение toString()
не имеет никакого эффекта:
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)
В PlayGround снова наблюдается другое поведение, которое использует собственное представление String для structs, т.е.
p // {x 10, y 20}
Есть ли способ изменить способ отображения экземпляра?
Ответы
Ответ 1
Swift 2 и 3
В Swift 2, Printable
стал CustomStringConvertible
. Например, вы можете создать несколько структур:
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)."
}
}
Если вы их инициализируете:
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])
Пользовательские описания появятся на вашей игровой площадке:
![введите описание изображения здесь]()
См. также CustomDebugStringConvertible
, который вы можете использовать для более подробного вывода во время отладки.
Замечание об использовании
Вы можете инициализировать String
из любого типа без реализации этого протокола. Например:
![введите описание изображения здесь]()
По этой причине документы говорят:
Использование CustomStringConvertible
в качестве общего ограничения или доступ к соответствующему типу description
напрямую, поэтому не рекомендуется.
Ответ 2
Соответствующие Apple Swift Docs
Apple предоставляет этот пример:
struct MyType: Printable {
var name = "Untitled"
var description: String {
return "MyType: \(name)"
}
}
let value = MyType()
println("Created a \(value)")
// prints "Created a MyType: Untitled"
Если вы попробуете это на игровой площадке, вы получите ту же самую проблему, что и вы (V11lldb_expr...
). На игровой площадке вы получите описание с правой стороны, когда вы вызываете инициализатор, но println
не возвращает что-то четкое.
Из игровой площадки, однако, этот код ведет себя так, как вы ожидали. Как ваш код, так и пример кода от Apple выше, напечатайте правильный description
, если он используется в контексте без игрового поля.
Я не думаю, что вы можете изменить это поведение на детской площадке. Это может быть просто ошибкой.
EDIT. Я уверен, что это ошибка. Я отправил отчет Apple об ошибке.
UPDATE. В Swift 2 вместо Printable
используйте CustomStringConvertible
(соответствующую ссылку doc).
struct MyType: CustomStringConvertible {
var name = "Untitled"
var description: String {
return "MyType: \(name)"
}
}
let value = MyType()
println("Created a \(value)")
// prints "Created a MyType: Untitled"
Ответ 3
Это, кажется, ошибка на игровой площадке. Если вы на самом деле компилируете и запускаете программу, она печатает:
(10, 20)
(10, 20)
(10, 20)
(10, 20)
как ожидалось.
Вы должны сообщить об этом в https://bugreport.apple.com
Ответ 4
Если вы откроете консольное представление:
Просмотр → Помощник редактора → Показать помощник редактора
вы можете увидеть ожидаемые строки печати
Проверено в xCode 6.3.2 с Yosimite 10.10
![enter image description here]()