2015-11-28 5 views
6

Implementierung Beachten Sie Folgendes:Swift Protokollerweiterung ein anderes Protokoll mit gemeinsamen zugehörigen Typ

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" 
    } 
} 

Dieser Code kompiliert wird. Aber wenn ich die explizite Definition des zugehörigen Typs typealias A = String auskommentiere, kann swiftc aus irgendeinem Grund den Typ nicht ableiten.

Ich spüre dies mit zwei zu tun hat Protokolle die gleichen Typen zugeordnet teilen aber ohne direkte Behauptung durch, zum Beispiel Typ Parametrierung (vielleicht zugehöriger Typ ist nicht mächtig/reif genug?), Die es macht mehrdeutig für Typschlussfolgerung.

Ich bin mir nicht sicher, ob dies ein Fehler/Unreife der Sprache ist, oder vielleicht, ich bin einige Nuancen in Protokollerweiterung fehle die zu Recht zu diesem Verhalten führen.

Kann jemand etwas Licht darauf werfen?

+0

, wenn Sie schnellen sagen nicht die Art zu folgern, was ist der Compiler-Fehler und auf der Linie? –

+0

@PatrickGoley Swift sieht 'hallo()' und 'hi()' 's nicht zurück und gibt' A' als äquivalenten Typ zurück und verlangt daher, dass ich 'hallo()' zusätzlich implementiere. Es sagt, dass "FooBarClass" dem Protokoll 'FooBar' nicht entsprechen kann –

+2

Ich denke, dass dies als ein Fehler betrachtet werden sollte. Der Workaround, den ich gefunden habe, deklariert 'typeias' im' FooBar'-Protokoll. zB: 'protocol FooBar: Foo {typealias A; func hi() -> A} ' – rintaro

Antwort

0

Für die Konformität mit dem Protokoll müssen explizite Werte für zugeordnete Typen in einem Protokoll angegeben werden. Dies kann durch harte erreicht werden, um eine Art Codierung, wie Sie mit typealias A = String, oder mit einem parametrisierten Typ getan haben, wie Sie erwähnten, wie unten:

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

Swift nicht Ihren zugehörigen Typen von einem implementierten Verfahren schließen das Protokoll, da es Unklarheit mit mehreren Methoden mit nicht übereinstimmenden Typen geben könnte. Aus diesem Grund müssen die Typien in Ihrer implementierenden Klasse explizit aufgelöst werden.

+0

Könnten Sie mehr über "wie es Mehrdeutigkeit mit mehreren Methoden mit nicht übereinstimmenden Typen sein könnte".? –

1

Blick auf dieses Beispiel

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" 
    } 
} 

mit Generika

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 
+1

Es ist erwähnenswert, dass dies ein Fehler im Swift-Compiler ist, und dass 'B' genauso benannt werden kann wie' A'. –

Verwandte Themen