Maybe I am missing something here, but bare with me. Say I have a protocol:
也许我在这里错过了什么,但对我来说是赤裸裸的。假设我有一个协议:
protocol Foo:Hashable, Comparable {}
And a struct that has this guy as a generic:
还有一个结构它有一个通用的
struct UsingFoo<T:Foo> {}
So far so good. Say I want to use Foo
on a second protocol:
目前为止一切都很顺利。假设我想在第二个协议上使用Foo:
protocol Bar {
associatedtype FooType:Foo
func doSomething(with:UsingFoo<FooType>)
}
And use Bar on a class:
在课堂上使用Bar:
class UsingBar<F:Foo>:Bar {
typealias FooType = F
func doSomething(with: UsingFoo<F>) {}
}
Now say I want to bring these guys to a party:
现在假设我要带这些人去参加一个聚会:
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())
}
}
The compiler says:
编译器说:
Cannot convert value of type 'UsingFoo<F>' to expected argument type 'UsingFoo<_>'
The question is: How can I ever use a property of type Bar
? As always, any comment very appreciated
问题是:如何使用Bar类型的属性?一如既往,任何评论都非常感谢
EDIT: Thanks to the accepted answer I figured out I should have specified FooType
. It would look like this:
编辑:感谢大家接受的答案,我发现我应该指定FooType。它看起来是这样的:
class FooBarParty<F:Foo, B:Bar> where B.FooType == F { ... }
1 个解决方案
#1
1
So the question here basically is:
所以这里的问题基本上是:
Why can't I use an instance of
B
to calldoSomething(UsingFoo<F>())
, but I can with an instance ofUsingBar<F>
为什么我不能使用一个B实例来调用doSomething(使用foo
())),但是我可以使用一个使用bar 的实例
The problem lies in your associated type - FooType
.
问题在于您的关联类型-页脚类型。
The doSomething
method says that it only accepts arguments of type UsingFoo<FooType>
. We know that in UsingBar<F>
, FooType
is F
. So UsingBar<F>().doSomething
requires a UsingFoo<F>
. And in thisWillCompile
, you give it a UsingFoo<F>
! It works!
doSomething方法说它只接受类型UsingFoo
Now you get another random instance of B
and call doSomething
. What argument does it need? UsingFoo<FooType>
, you might say. Well, what is FooType
here? We don't know! It can be F
, or String
if we add this extension right here:
现在你得到另一个B的随机实例,然后调用doSomething。它需要什么论据?UsingFoo < FooType >,你可能会说。那么,FooType是什么呢?我们不知道!它可以是F,也可以是字符串如果我们在这里加上这个扩展:
extension String: Foo { }
FooType
can be anything that implements Foo
. It doesn't need to be F
. But you're passing it a UsingFoo<F>
. That's why it does not work!
FooType可以是任何实现Foo的东西。它不一定是F,但你传递它为UsingFoo
As you said, this line does not work either:
正如你所说的,这条线也不管用:
self.b = UsingBar<F>.init()
You need to be aware that B
is not Bar
. It can be any type that implements Bar
, not necessarily UsingBar<F>
. What you're doing is essentially:
你需要知道B不是Bar。它可以是任何实现Bar的类型,不一定使用Bar
class A {}
class B: A {}
class C: A {}
let obj: B = C()
That's why that does not compile.
这就是为什么它不编译的原因。
#1
1
So the question here basically is:
所以这里的问题基本上是:
Why can't I use an instance of
B
to calldoSomething(UsingFoo<F>())
, but I can with an instance ofUsingBar<F>
为什么我不能使用一个B实例来调用doSomething(使用foo
())),但是我可以使用一个使用bar 的实例
The problem lies in your associated type - FooType
.
问题在于您的关联类型-页脚类型。
The doSomething
method says that it only accepts arguments of type UsingFoo<FooType>
. We know that in UsingBar<F>
, FooType
is F
. So UsingBar<F>().doSomething
requires a UsingFoo<F>
. And in thisWillCompile
, you give it a UsingFoo<F>
! It works!
doSomething方法说它只接受类型UsingFoo
Now you get another random instance of B
and call doSomething
. What argument does it need? UsingFoo<FooType>
, you might say. Well, what is FooType
here? We don't know! It can be F
, or String
if we add this extension right here:
现在你得到另一个B的随机实例,然后调用doSomething。它需要什么论据?UsingFoo < FooType >,你可能会说。那么,FooType是什么呢?我们不知道!它可以是F,也可以是字符串如果我们在这里加上这个扩展:
extension String: Foo { }
FooType
can be anything that implements Foo
. It doesn't need to be F
. But you're passing it a UsingFoo<F>
. That's why it does not work!
FooType可以是任何实现Foo的东西。它不一定是F,但你传递它为UsingFoo
As you said, this line does not work either:
正如你所说的,这条线也不管用:
self.b = UsingBar<F>.init()
You need to be aware that B
is not Bar
. It can be any type that implements Bar
, not necessarily UsingBar<F>
. What you're doing is essentially:
你需要知道B不是Bar。它可以是任何实现Bar的类型,不一定使用Bar
class A {}
class B: A {}
class C: A {}
let obj: B = C()
That's why that does not compile.
这就是为什么它不编译的原因。