Подтвердить что ты не робот

Как изменить текстовое представление, отображаемое для типа в 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}

Есть ли способ изменить способ отображения экземпляра?

4b9b3361

Ответ 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