我试图更新我编写的一些旧代码,基本上看起来像:
trait Foo<T>{}
struct Bar<A, B: Foo<A>>{
b: B
}
这曾经完全正常,但现在我收到编译错误:
src/test.rs:19:12: 19:13 error: parameter `A` is never used
src/test.rs:19 struct Bar<A, B: Foo<A>> {
^
src/test.rs:19:12: 19:13 help: consider removing `A` or using a marker such as `core::marker::PhantomData`
所以我可以尝试删除类型参数并获得如下内容:
struct Bar<A>{
b: Foo<A>
}
然而,这并不是我想要的。在我的原始代码中,B
解析为大小不一的类型,但现在Foo<A>
已取消确定。
另一个建议的解决方案是尝试使用此错误提及的PhantomData,从而产生:
struct Bar<A, B: Foo<A>> {
b: B,
marker: PhantomData<A>
}
但这对我来说似乎很麻烦。阅读PhantomData
的文档似乎表明这是用于不安全的代码,但我不在这里的任何地方使用不安全的代码。我想要的只是Bar
包含一个实现Foo
的实例。
这真的是现在处理这种情况的唯一方法,还是我错过了什么?
答案 0 :(得分:4)
取决于您的真实 <unknown>:0: error: bridging header '/Users/welch/Desktop/DONT DELETE/My Project/My_Project/My_Project-Bridging-Header.h' does not exist
的方式,您可以使用相关类型,例如:
Foo
否则(如果你确实需要trait Foo{ type T; }
struct Bar<B: Foo> {
b: B,
}
上的类型参数),Foo
确实是要走的路。
您并不是唯一一个发现PhantomData
的文档令人困惑的人(请参阅PhantomData
is incomprehensible)。因此,documentation for PhantomData
已recently improved by Steve Klabnik,现在它确实明确提到了这种情况(而不仅仅是不安全的代码)。
答案 1 :(得分:1)
似乎您想要的是以下内容:对于任何类型A
,B
必须实现Foo<A>
。这表明您依赖Foo
的功能而不依赖于A
的值,这意味着您可以将Foo
更改为具有关联类型而不是类型参数。< / p>
trait Foo<T> { }
将成为
trait Foo {
type T;
}
然后,您可以在任何地方删除A
类型参数,只需要B: Foo
。
详细说明PhantomData
,它与不安全代码无关,它用于在编译器无法推断时确定类型参数的方差。有关差异和PhantomData
的详细信息,请参阅RFC 738。