Как я могу изменить текстовый вывод, который отображается при интерполяции строк?
Printable
Протокол выглядит наиболее очевидные , но оно игнорируется в обеих Струнной Интерполяции и при печати экземпляра, например:
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 для структур, то есть:
p // {x 10, y 20}
Есть ли способ изменить способ отображения экземпляра?
Ответы:
Swift 2–4
Резюме
Соответствовать
CustomStringConvertible
протоколу и добавитьdescription
:var description: String { return "description here" }
пример
Вы можете создать несколько структур:
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
, что можно использовать для более подробного вывода во время отладки.Примечание по использованию
Вы можете инициализировать a
String
из любого типа без реализации этого протокола. Например:По этой причине в документах говорится:
источник
Соответствующие документы Apple Swift
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
при использовании в контексте, не связанном с игровой площадкой.Я не думаю, что вы можете изменить это поведение на детской площадке. Это также могло быть просто ошибкой.
РЕДАКТИРОВАТЬ : я почти уверен, что это ошибка; Я отправил в Apple отчет об ошибке.
ОБНОВЛЕНИЕ : в Swift 2 вместо этого
Printable
используйтеCustomStringConvertible
( соответствующую ссылку на документ ).struct MyType: CustomStringConvertible { var name = "Untitled" var description: String { return "MyType: \(name)" } } let value = MyType() println("Created a \(value)") // prints "Created a MyType: Untitled"
источник
Похоже, это ошибка на детской площадке. Если вы действительно скомпилируете и запустите программу, она напечатает:
(10, 20) (10, 20) (10, 20) (10, 20)
как и ожидалось.
Вы должны сообщить об этом на https://bugreport.apple.com.
источник
Если вы откроете консоль: View -> Assistant Editor -> Show Assistant Editor, вы увидите ожидаемые строки печати. Проверено в xCode 6.3.2 с помощью Yosimite 10.10.
источник
В качестве альтернативы в Swift 5+ вы можете расширить String.StringInterpolation
struct Point { var x : Int var y : Int } extension String.StringInterpolation { mutating func appendInterpolation(_ value: Point) { appendInterpolation("\(value.x):\(value.y)") } }
Это изменит значение для,
print("\(p)")
но не дляprint(p)
- которое по-прежнему будет использовать описаниеисточник
AppCode
предоставляетGenerate| debugDescription
и «Создать | описание`. Лучше печатать их для структуры с большим количеством членов.источник