以下代码使用具有泛型类型的结构.虽然它的实现仅对给定的特征边界有效,但可以使用或不使用相同的边界来定义结构.struct的字段是私有的,因此无论如何其他代码都无法创建实例.
trait Trait {
fn foo(&self);
}
struct Object<T: Trait> {
value: T,
}
impl<T: Trait> Object<T> {
fn bar(object: Object<T>) {
object.value.foo();
}
}
Run Code Online (Sandbox Code Playgroud)
是否应该忽略对结构有约束力的特性以符合DRY原则,还是应该给予澄清依赖性?或者是否存在一种解决方案应优先于另一种解决方案?
我有一个包含函数对象的结构:
struct Foo<F> {
func: F,
}
Run Code Online (Sandbox Code Playgroud)
我想添加Fn绑定到结构定义的特征.问题是:我确实关心第一个参数(必须是i32),而不是第二个参数.我真正想写的是这样的:
struct Foo<F>
where
? P so that F: Fn(i32, P),
{
func: F,
}
Run Code Online (Sandbox Code Playgroud)
所以在英语中:类型F必须是一个带有两个参数的函数,第一个是i32(和第二个可以是任何东西).上面的语法显然无效.我想到了三个可能的解决方案:
该for<>语法不会帮助这里.除了它对非寿命参数不起作用的事实之外,它是通用的("为所有人")而不是存在的("存在").所以那就是了.
另一种可能性是向结构添加类型参数.我已经不喜欢那个解决方案了,因为参数本身并不属于struct.
struct Foo<F, P>
where
F: Fn(i32, P),
{
func: F,
}
Run Code Online (Sandbox Code Playgroud)
但是这不起作用:P除了where绑定之外没有使用参数,所以编译器会抱怨.
这个问题可以通过添加一个PhantomData<P>字段来解决,但这不是必需的,更重要的是,用户不能再轻易使用struct constructor语法了.
最后我试过这个:
struct Foo<F>
where
F: Fn(i32, _),
{
func: F,
}
Run Code Online (Sandbox Code Playgroud)
但这也行不通:
error[E0121]: the type placeholder `_` is not allowed within types on item signatures …Run Code Online (Sandbox Code Playgroud)use std::iter::Iterator;
trait ListTerm<'a> {
type Iter: Iterator<Item = &'a u32>;
fn iter(&'a self) -> Self::Iter;
}
enum TermValue<'a, LT>
where
LT: ListTerm<'a> + Sized + 'a,
{
Str(LT),
}
Run Code Online (Sandbox Code Playgroud)
error[E0392]: parameter `'a` is never used
--> src/main.rs:8:16
|
8 | enum TermValue<'a, LT>
| ^^ unused type parameter
|
= help: consider removing `'a` or using a marker such as `std::marker::PhantomData`
Run Code Online (Sandbox Code Playgroud)
'a显然正在被使用.这是一个错误,还是参数枚举还没有真正完成?rustc --explain E0392建议使用PhantomData<&'a _>,但我认为在我的用例中没有任何机会这样做.