如何在结构中使用未使用的类型参数?

时间:2015-04-26 14:33:08

标签: rust

我试图更新我编写的一些旧代码,基本上看起来像:

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的实例。

这真的是现在处理这种情况的唯一方法,还是我错过了什么?

2 个答案:

答案 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 PhantomDatarecently improved by Steve Klabnik,现在它确实明确提到了这种情况(而不仅仅是不安全的代码)。

答案 1 :(得分:1)

似乎您想要的是以下内容:对于任何类型AB必须实现Foo<A>。这表明您依赖Foo的功能而不依赖于A的值,这意味着您可以将Foo更改为具有关联类型而不是类型参数。< / p>

trait Foo<T> { }

将成为

trait Foo {
    type T;
}

然后,您可以在任何地方删除A类型参数,只需要B: Foo

详细说明PhantomData,它与不安全代码无关,它用于在编译器无法推断时确定类型参数的方差。有关差异和PhantomData的详细信息,请参阅RFC 738

相关问题