【发布时间】:2021-01-29 19:45:35
【问题描述】:
我正在尝试创建一个泛型结构,并具有泛型实现特征的界限。该特征本身是通用的。这是在 Rust 1.49.0 中。
如果我这样做:
trait Foo<T> {}
struct Baz<F: Foo<T>> {
x: F,
}
我收到编译错误,因为 T 未定义。但如果我定义它:
trait Foo<T> {}
struct Baz<T, F: Foo<T>> {
x: F,
}
然后我得到一个编译器错误,因为 T 未使用。
唯一的选择似乎是包含一个PhantomData<T> 字段,但如果我的通用依赖变得更加复杂,这将开始变得更加笨拙:
use std::marker::PhantomData;
trait Foo<T> {}
struct Baz<T, U, F: Foo<T>, G: Foo<U>> {
phantom_t: PhantomData<T>,
phantom_u: PhantomData<U>,
x: F,
y: G,
}
我的一半领域是幻影!该结构实际上是闹鬼的。
我的问题是:最后编译的示例真的是惯用的 Rust 吗?如果是这样,为什么 Rust 不能检测到 Baz<T, Foo<T>> 中的 T 确实被使用了?
【问题讨论】:
-
为什么
F实现Foo<T>是必要的,如果它为哪个T实现它并不重要?如果F同时实现Foo<i32>和Foo<u32>,T的选择对Baz<F>有何影响? -
首先我不能只做
struct Baz<F: Foo<T>> { x: F},因为我得到一个编译器错误。但总的来说,我可能想限制T。或者我可能有一个看起来像Baz<F: Foo<T>, G: Foo<T>>的结构定义。我对T没有任何限制,但F和G(可能不同)必须为相同T实现Foo<T>。 -
struct Baz<F> { x: F }是我的意思。在任何情况下,如果您确实走PhantomData路线,重要的是要知道什么样的幻影困扰着您。我已经添加了答案。