我对 Rust 很陌生,我一直遇到这个问题,我不知道如何解决它。我有一个类似的结构,
pub struct Solver <'e, E: 'e, T, M, C>
where
E: Equation<T, M, C>,
T: Term<C>,
M: Mesh,
{
equations: &'e [E],
}
Run Code Online (Sandbox Code Playgroud)
这总是给我这个错误,
pub struct Solver <'e, E: 'e, T, M, C>
where
E: Equation<T, M, C>,
T: Term<C>,
M: Mesh,
{
equations: &'e [E],
}
Run Code Online (Sandbox Code Playgroud)
我知道它T从未被使用过,但是,例如,我无法定义方程式T(或者我可以吗?)。有没有更短的版本可以写?这PhantomData是我想避免的奇怪的事情,所以我不知道如何解决这个问题。
当为泛型绑定类型时,绑定仅对使用绑定类型的功能(调用其方法或访问其字段等)的编译器有意义。通常没有必要以其他方式限制事物。这样做是有原因的,但最好仅在意识到需要时才添加这些理由。声明泛型参数时,同样适用。impl除非在结构中显式使用该参数,否则无论是否需要它都可能不需要添加它。
在下面的代码中,除了将其保存在数组中之外,Solver没有执行任何操作,因此可以是任何类型。E它很灵活。
pub trait Equation
{
type T;
fn eq(&self) -> Self::T;
}
pub struct Solver<'e, E: 'e>
{
equations: &'e [E],
}
impl<'e, E: 'e> Solver<'e, E>
{
fn get_e(&self, i: usize) -> &'e E
{
&self.equations[i]
}
}
Run Code Online (Sandbox Code Playgroud)
现在假设Solver需要调用其数组中 的eq()方法。不过,到目前为止,还没有必要在结构定义中E设置界限。E边界仅在实现中才有意义。
pub struct Solver<'e, E: 'e>
{
equations: &'e [E],
}
impl<'e, E: 'e, F> Solver<'e, E>
where
E: Equation<T = F>,
{
fn get_e(&self, i: usize) -> &'e E
{
&self.equations[i]
}
fn e_eq(&self, i: usize) -> F
{
self.equations[i].eq()
}
}
Run Code Online (Sandbox Code Playgroud)
上面的内容编译得很好。该结构只关心它具有E任何类型并且其生命周期遵循'e. 并且impl有必要变得更加具体。
forimpl结构在这方面可以有些独立。直到需要调用它的返回.eq()类型并对其返回类型执行某些操作时,我们才添加任何约束。并且添加了一个新的通用参数,因为它必须是 - 立即使用它并且编译器会感到满意。
上面,返回的特定类型.eq()被推迟到泛型参数F。到目前为止,Solver可以接受任何E返回任何T尚未定义的类型(与Solver's相关联F)并从 中返回它e_eq()。
为了更多地限制事物并确保任何从其方法返回 an 的E东西都可以被消除,并且类型在 的边界中指定:Solveri32eq()FE
impl<'e, E: 'e> Solver<'e, E>
where
E: Equation<T = i32>,
{
fn get_e(&self, i: usize) -> &'e E
{
&self.equations[i]
}
fn e_eq(&self, i: usize) -> i32
{
self.equations[i].eq()
}
}
Run Code Online (Sandbox Code Playgroud)
Solver到目前为止,所有的更改都是必然的,并且没有影响s struct的定义- 只是影响impl.
我个人发现推迟这样的事情是一个很好的方法。根据需要增量添加边界,同时不断确保代码构建过程中的每一步都可以节省时间,而不是提前声明几件事。如果我想到需要添加的几件事,我会将它们放在 TODO 注释中,然后一次修改一项。
如果您正在处理某种设计文档,而队友正在实现依赖于您提供的部分的内容,您可以将所需的方法添加到 并在impl需要的范围内工作,并保留方法主体空的unimplemented!(),里面有一个宏。让编译器提示您需要添加哪些边界。
struct仅当存在公共字段时才需要声明中的严格约束,并且程序的其他部分对这些字段支持哪些接口或属性进行假设。