6

次の点を考慮してください。

protocol Foo {
  typealias A
  func hello() -> A
}
protocol FooBar: Foo {
  func hi() -> A
}
extension FooBar {
  func hello() -> A {
    return hi()
  }
}

class FooBarClass: FooBar {
  typealias A = String
  func hi() -> String {
    return "hello world"
  }
}

このコードはコンパイルされます。しかし、関連付けられた type の明示的な定義をコメントアウトするとtypealias A = String、何らかの理由で、swiftc は型の推測に失敗します。

これは、同じ関連付けられた型を共有する 2 つのプロトコルに関係していると感じていますが、たとえば、型のパラメーター化 (おそらく関連付けられた型は強力ではないか、十分に成熟していないのでしょうか?) による直接的なアサーションはなく、型の推論が曖昧になります。

これが言語のバグ/未熟なのかどうかはわかりません。それとも、この動作に正当につながるプロトコル拡張のニュアンスが欠けているのかもしれません。

誰かがこれに光を当てることができますか?

4

2 に答える 2

1

この例を見てください

protocol Foo {
    typealias A
    func hello() -> A
}
protocol FooBar: Foo {
    typealias B
    func hi() -> B
}
extension FooBar {
    func hello() -> B {
        return hi()
    }
}

class FooBarClass: FooBar {
    //typealias A = String
    func hi() -> String {
        return "hello world"
    }
}

ジェネリックで

class FooBarClass<T>: FooBar {
    var t: T?
    func hi() -> T? {
        return t
    }
}

let fbc: FooBarClass<Int> = FooBarClass()
fbc.t = 10
fbc.hello() // 10
fbc.hi()    // 10
于 2015-11-28T19:37:04.593 に答える
0

プロトコルに準拠するには、プロトコルに関連付けられた型に明示的な値を提供する必要があります。これは、 で行ったように型をハードコーディングするtypealias A = Stringか、以下のようにパラメーター化された型を使用することで実現できます。

class FooBarClass<T>: FooBar {
    typealias A = T
    ...
}

Swift は、プロトコルの実装されたメソッドから関連付けられた型を推測しません。これは、型が一致しない複数のメソッドがあいまいになる可能性があるためです。これが、実装クラスで typealias を明示的に解決する必要がある理由です。

于 2015-11-28T06:37:54.723 に答える