Swiftでタイプに表示されるテキスト表現を変更するにはどうすればよいですか?


91

文字列補間で表示されるテキスト出力を変更するにはどうすればよいですか?

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では、動作が再び異なります。

p // {x 10, y 20}

インスタンスの表示方法を変更する方法はありますか?


上記のコードは、Xcode 6.3ベータ4のプレイグラウンドで期待どおりに機能します
carbo18

回答:


112

スウィフト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。デバッグ中の詳細な出力に使用できます。


使用上の注意

このプロトコル実装しなくてStringも、任意のタイプの初期化できます。例えば:

ここに画像の説明を入力してください

このため、ドキュメントでは次のように述べています。

したがってCustomStringConvertible、一般的な制約として使用したり、適合タイプのにdescription直接アクセスしたりすることはお勧めしません。


37

関連する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が、非プレイグラウンドコンテキストで使用された場合、正しい出力をします。

遊び場でこの振る舞いを変えることはできないと思います。また、単なるバグの可能性もあります。

編集:私はこれがバグであることをかなり確信しています。バグレポートをアップルに提出しました。

更新: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"

2

これは遊び場のバグのようです。実際にプログラムをコンパイルして実行すると、通常は次のように出力されます。

(10, 20)
(10, 20)
(10, 20)
(10, 20)

予想通り。

https://bugreport.apple.comでこれを報告する必要があります


0

コンソールビューを開くと、[表示]-> [アシスタントエディター]-> [アシスタントエディターを表示]に、Yosimite 10.10を使用したxCode 6.3.2でチェックされた期待される印刷行が表示されます。

ここに画像の説明を入力してください


0

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)-まだ記述を使用しますどの


0

AppCodeを提供しGenerate| debugDescription、「生成| 説明 `。多くのメンバーと一緒に構造体を入力するのに勝る。

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.