相关疑难解决方法(0)

是否应该在struct和impl中复制特征边界?

以下代码使用具有泛型类型的结构.虽然它的实现仅对给定的特征边界有效,但可以使用或不使用相同的边界来定义结构.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原则,还是应该给予澄清依赖性?或者是否存在一种解决方案应优先于另一种解决方案?

rust

13
推荐指数
3
解决办法
725
查看次数

在结构定义上指定`Fn`特性,而不修复其中一个`Fn`参数

我有一个包含函数对象的结构:

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(和第二个可以是任何东西).上面的语法显然无效.我想到了三个可能的解决方案:

  1. for<>语法不会帮助这里.除了它对非寿命参数不起作用的事实之外,它是通用的("为所有人")而不是存在的("存在").所以那就是了.

  2. 另一种可能性是向结构添加类型参数.我已经不喜欢那个解决方案了,因为参数本身并不属于struct.

    struct Foo<F, P> 
    where
        F: Fn(i32, P),
    {
        func: F,
    }
    
    Run Code Online (Sandbox Code Playgroud)

    但是这不起作用:P除了where绑定之外没有使用参数,所以编译器会抱怨.

    这个问题可以通过添加一个PhantomData<P>字段来解决,但这不是必需的,更重要的是,用户不能再轻易使用struct constructor语法了.

  3. 最后我试过这个:

    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)

generics traits rust

9
推荐指数
2
解决办法
242
查看次数

在impl块或方法上指定特征绑定是否更好?

假设我想创建一些包含其他泛型类型的类型,如下所示:

struct MyWrapper<T> {
    pub inner: T,
}
Run Code Online (Sandbox Code Playgroud)

现在我希望我的类型有一个方法,如果内部类型满足特定的绑定.例如:我想打印它(在这个例子中没有使用fmt特征来简化).为此,我有两种可能性:向impl方法本身添加绑定.

方法绑定

impl<T> MyWrapper<T> {
    pub fn print_inner(&self) where T: std::fmt::Display {
        println!("[[ {} ]]", self.inner);
    }
}
Run Code Online (Sandbox Code Playgroud)

MyWrapper<()>我得到一个调用此函数时:

error[E0277]: `()` doesn't implement `std::fmt::Display`
  --> src/main.rs:20:7
   |
20 |     w.print_inner();
   |       ^^^^^^^^^^^ `()` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string
   |
   = help: the trait `std::fmt::Display` is not implemented for `()`
Run Code Online (Sandbox Code Playgroud)

Impl Bound

impl<T: std::fmt::Display> …
Run Code Online (Sandbox Code Playgroud)

traits rust

7
推荐指数
1
解决办法
1357
查看次数

如何在此结构定义中避免使用PhantomData?

我有一个看起来像这样的特征:

trait Handler<C> {
    fn handle(&self, msg: &Message, connection: &mut C);
}
Run Code Online (Sandbox Code Playgroud)

实例应该像链接HTTP处理程序的中间件一样被链接:

let handler = FirstHandler {
     next: SecondHandler {
         next: FinalHandler {},
     },
};
Run Code Online (Sandbox Code Playgroud)

每种处理程序类型都可以对类型施加额外的约束C:

trait ConnectionThatWorksWithFirstHandler {
    ...
}

struct FirstHandler<C: ConnectionThatWorksWithFirstHandler, H: Handler<C>> {
    next: H,
    _phantom: PhantomData<C>,
}
Run Code Online (Sandbox Code Playgroud)

正如你在这里看到的,我需要一个PhantomData<C>避免错误E0392(parameter C is never used).但是,PhantomData在语义上是错误的,因为处理程序没有持有实例C.这很难看.例如,我手动必须提供正确的同步/发送特征实现:

unsafe impl<C: ConnectionThatWorksWithFirstHandler, H: Handler<C>> Send for Handler<C, H> where H: Send {}
unsafe impl<C: ConnectionThatWorksWithFirstHandler, H: Handler<C>> Sync for Handler<C, H> where H: …
Run Code Online (Sandbox Code Playgroud)

traits rust

5
推荐指数
1
解决办法
131
查看次数

具有通用特征的结构,这也是通用特征

在 Rust 1.15 中,我创建了一个特征来抽象读取和解析文件格式。我正在尝试创建一个内部具有此通用特征的结构。

我有这个特点:

use std::io::Read;

trait MyReader<R: Read> {
    fn new(R) -> Self;
    fn into_inner(self) -> R;

    fn get_next(&mut self) -> Option<u32>;
    fn do_thingie(&mut self);
}
Run Code Online (Sandbox Code Playgroud)

我想创建一个结构,它引用了实现这个的东西。

struct MyIterThing<'a, T: MyReader<R>+'a> {
    inner: &'a mut T,
}
Run Code Online (Sandbox Code Playgroud)

给出以下错误:

use std::io::Read;

trait MyReader<R: Read> {
    fn new(R) -> Self;
    fn into_inner(self) -> R;

    fn get_next(&mut self) -> Option<u32>;
    fn do_thingie(&mut self);
}
Run Code Online (Sandbox Code Playgroud)

T: MyReader+'a, 我收到错误: "error[E0243]: wrong number of type arguments: expected 1, found 0",T: MyReader<R: …

traits rust

3
推荐指数
1
解决办法
1128
查看次数

标签 统计

rust ×5

traits ×4

generics ×1