【问题标题】:Cannot convert value of generic type to expected argument of associated type无法将泛型类型的值转换为关联类型的预期参数
【发布时间】:2017-03-09 13:23:50
【问题描述】:

假设我有一个协议:

protocol Foo:Hashable, Comparable {}

还有一个将这个家伙作为泛型的结构:

struct UsingFoo<T:Foo> {}

到目前为止一切顺利。假设我想在第二个协议上使用Foo

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

并在类上使用 Bar:

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 { ... }

【问题讨论】:

    标签: ios swift generics swift3


    【解决方案1】:

    所以这里的问题基本上是:

    为什么我不能使用B 的实例调用doSomething(UsingFoo&lt;F&gt;()),但我可以使用UsingBar&lt;F&gt; 的实例

    问题在于您的关联类型 - FooType

    doSomething 方法说它只接受UsingFoo&lt;FooType&gt; 类型的参数。我们知道在UsingBar&lt;F&gt; 中,FooTypeF。所以UsingBar&lt;F&gt;().doSomething 需要UsingFoo&lt;F&gt;。在thisWillCompile,你给它一个UsingFoo&lt;F&gt;!有效!

    现在你得到另一个B 的随机实例并调用doSomething。需要什么论证? UsingFoo&lt;FooType&gt;,你可能会说。那么,这里的FooType 是什么?我们不知道!如果我们在此处添加此扩展程序,则可以是 FString

    extension String: Foo { }
    

    FooType 可以是任何实现Foo 的东西。它不需要是F。但是您将其传递给UsingFoo&lt;F&gt;。这就是为什么它不起作用!

    正如你所说,这条线也不起作用:

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

    您需要注意B 不是 Bar。它可以是任何实现Bar 的类型,不一定是UsingBar&lt;F&gt;。你所做的基本上是:

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

    这就是为什么它不能编译。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-27
      • 2016-07-02
      • 2016-03-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多