rust - 预期的关闭,发现不同的关闭

标签 rust

A 是一个包含B 向量的结构。 A 实现了 add_b 方法,该方法将 B 实例添加到 B 的列表中。 B 包含闭包属性 f

如果我使用 add_b 将一个 B 添加到向量中,就可以了。如果我用 add_b 添加两个向量,我会收到一个错误,指出两个闭包不同。这是一个最小的例子:

// A struct...
struct A<F> {
    b_vec: Vec<B<F>>, // A vector of B
}

// ...and its implementation
impl<F> A<F>
where
    F: Fn(),
{
    fn new() -> A<F> {
        A { b_vec: Vec::new() }
    }

    fn add_b(&mut self, b: B<F>) {
        self.b_vec.push(b);
    }
}

// B struct...
struct B<F> {
    f: F,
}

// ...and its implementation
impl<F> B<F>
where
    F: Fn(),
{
    fn new(f: F) -> B<F> {
        B { f: f }
    }
}

// I add two B (with their closures arguments) in A
fn main() {
    let mut a = A::new();
    a.add_b(B::new(|| println!("test")));
    a.add_b(B::new(|| println!("test2")));
}

此代码导致:

error[E0308]: mismatched types
  --> src/main.rs:39:20
   |
39 |     a.add_b(B::new(|| println!("test2")));
   |                    ^^^^^^^^^^^^^^^^^^^^ expected closure, found a different closure
   |

如何将多个 B 及其不同的闭包添加到 Ab_vec

最佳答案

查看完整编译器输出总是值得的:

error[E0308]: mismatched types
  --> src/main.rs:39:20
   |
39 |     a.add_b(B::new(|| println!("test2")));
   |                    ^^^^^^^^^^^^^^^^^^^^ expected closure, found a different closure
   |
   = note: expected type `[closure@src/main.rs:38:20: 38:39]`
              found type `[closure@src/main.rs:39:20: 39:40]`
   = note: no two closures, even if identical, have the same type
   = help: consider boxing your closure and/or using it as a trait object

特别有帮助:

  • no two closures, even if identical, have the same type

  • consider boxing your closure and/or using it as a trait object

我们可以通过删除 B 类型来进一步简化您的示例共。那么唯一的任务就是保存一个闭包向量。正如编译器告诉我们的,没有两个闭包具有相同的类型,但是 Vec是同构数据结构,这意味着其中的每个项目都具有相同的类型。

我们可以通过引入一层间接来解决这个限制。正如编译器建议的那样,这可以通过特征对象或装箱(后一种包括第一种)来完成。相应的类型如下所示:

  • Vec<&Fn()> (对特征对象的引用)
  • Vec<Box<Fn()>> (盒子里的特征对象)

在您的示例中,您希望拥有 所有闭包,因此正确的选择是将所有闭包装箱,如Box<T>是一个拥有包装器,而引用只借用东西。

一个完整的例子:

struct A {
    b_vec: Vec<B>,
}

impl A {
    fn new() -> A {
        A { b_vec: Vec::new() }
    }

    fn add_b(&mut self, b: B) {
        self.b_vec.push(b);
    }
}

struct B {
    f: Box<Fn()>,
}

impl B {
    fn new<F>(f: F) -> B
    where
        F: Fn() + 'static,
    {
        B { f: Box::new(f) }
    }
}

fn main() {
    let mut a = A::new();
    a.add_b(B::new(|| println!("test")));
    a.add_b(B::new(|| println!("test2")));
}

关于rust - 预期的关闭,发现不同的关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53755578/

相关文章:

c - 在 C 程序中嵌入 Rust 任务?

io - 相当于 Python 的 subprocess.communicate 在 Rust 中?

rust - 如何为使用生命周期实现的特征传递函数?

rust - Rust 的类型推断如何跨多个语句工作?

rust - 如何在 rust 中将迭代器保存在结构中

rust - 在链接列表上创建可变迭代器时无法移出借用的内容

rust - 从 Rust 中的 HashMap 中删除随机条目

rust - 如何在 Rust 中过滤特定子特征的 RCed 特征对象向量?

rust - 在惰性静态 RwLock<Option<T>> 中返回对 T 的引用?

rust - 有什么办法可以让通用函数使用专用函数吗?