2017-03-09 45 views
1

也許我在這裏失去了一些東西,但與我一起裸露。 說我有一個協議:無法將泛型類型的值轉換爲關聯類型的預期參數

protocol Foo:Hashable, Comparable {} 

和具有這個傢伙作爲一個通用的一個結構:

struct UsingFoo<T:Foo> {} 

到目前爲止好。說我想第二協議使用Foo

protocol Bar { 
    associatedtype FooType:Foo 
    func doSomething(with:UsingFoo<FooType>) 
} 

而上一類使用吧:

class UsingBar<F:Foo>:Bar { 
    typealias FooType = F 
    func doSomething(with: UsingFoo<F>) {} 
} 

現在說我想要把這些傢伙的一方:

class FooBarParty<F:Foo, B:Bar>: NSObject { 
    var b:B 
    init(b:B) { 
     self.b = b 
     // interestingly, this line below won't compile 
     // self.b = UsingBar<F>.init() 
    } 

    func thisWillCompile() { 
     UsingBar<F>.init().doSomething(with: UsingFoo<F>.init()) 
    } 

    func thisWontCompile() { 
     b.doSomething(with: UsingFoo<F>.init()) 
    } 

    func thisAlsoWont (anotherB:B) { 
     anotherB.doSomething(with: UsingFoo<F>.init()) 
    } 
} 

編譯器說:

Cannot convert value of type 'UsingFoo<F>' to expected argument type 'UsingFoo<_>' 

問題是:我如何使用Bar類型的房產?與往常一樣,任何意見非常讚賞

編輯:感謝接受的答案我想通了,我應該指定FooType。它應該是這樣的:

class FooBarParty<F:Foo, B:Bar> where B.FooType == F { ... } 

回答

1

所以這裏的問題主要是:

爲什麼我不能用的B實例調用doSomething(UsingFoo<F>()),但我可以接受的UsingBar<F>

實例

問題在於您的關聯類型 - FooType

doSomething方法說它只接受UsingFoo<FooType>類型的參數。我們知道在UsingBar<F>,FooTypeF。所以UsingBar<F>().doSomething需要UsingFoo<F>。在thisWillCompile中,你給它一個UsingFoo<F>!有用!

現在您將獲得另一個B的隨機實例,並致電doSomething。它需要什麼論點? UsingFoo<FooType>,你可能會說。那麼,FooType在這裏是什麼?我們不知道!它可以是F,或String如果我們在這裏添加此擴展:

extension String: Foo { } 

FooType可以是任何實現Foo。它不需要是F。但你通過它UsingFoo<F>。這就是爲什麼它不起作用!

正如你所說,這行不工作,要麼:

self.b = UsingBar<F>.init() 

你需要知道BBar。它可以是實現Bar的任何類型,不一定是UsingBar<F>。你在做什麼實質上是:

class A {} 
class B: A {} 
class C: A {} 
let obj: B = C() 

這就是爲什麼不編譯。

相關問題