为什么我会收到“parameter is never used [E0392]”错误提示?

17

我正在尝试在Rust中实现八叉树。该八叉树是针对一种具有通用特性的类型进行泛型化设计的,该类型应实现一个通用特征:

pub trait Generable<U> {
    fn generate_children(&self, data: &U) -> Vec<Option<Self>>;
}

pub enum Octree<T, U>
where
    T: Generable<U>,
{
    Node {
        data: T,
        children: Vec<Box<Octree<T, U>>>,
    },
    Empty,
    Uninitialized,
}

这里有一个在Playground上重现该问题的简化示例 这会生成一个错误:
error[E0392]: parameter `U` is never used
 --> src/main.rs:5:20
  |
5 | pub enum Octree<T, U>
  |                    ^ unused type parameter
  |
  = help: consider removing `U` or using a marker such as `std::marker::PhantomData`

从签名中删除U会导致"未声明类型名称 'U'"。

我是做错了什么还是这是一个bug?如何正确地操作?


2
看起来是编译器的限制,你可以尝试通过使用PhantomData来绕过它,添加一个“假”的成员PhantomData<*const U>,在等待更确切的答案时。 - Matthieu M.
谢谢,那很有帮助。虽然如果能不用PhantomData就更好了 ;) - ebvalaim
不客气 :) 我真的很想知道你的代码是应该被拒绝还是编译器出了问题... - Matthieu M.
我在Github上找到了一个类似的问题(https://github.com/rust-lang/rust/issues/26283),那里有人认为这是编译器的限制,但我不确定是否完全相同... - ebvalaim
1个回答

12

我不认为你想要另一个普通的东西在这里,你需要一个关联类型:

pub trait Generable {
    type From;
    fn generate_children(&self, data: &Self::From) -> Vec<Option<Self>>
    where
        Self: Sized;
}

pub enum Octree<T>
where
    T: Generable,
{
    Node {
        data: T,
        children: Vec<Box<Octree<T>>>,
    },
    Empty,
    Uninitialized,
}

fn main() {}

顺带一提,Vec<Box<Octree<T>>> 可能会多出一个间接层级——你可以直接使用 Vec<Octree<T>>


从1.31.1版本开始,我们需要在Self上添加Sized限定;pub trait Generable where Self:Sized { ... - vikram2784

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接