Rust 如何在方法中调用闭包

Rust 如何在方法中调用闭包,rust,Rust,我尝试从为结构a实现的do\u something调用一个闭包。我读了一些关于这个的帖子,但我现在有点迷路了。以下是一个简化版本: // A simple structure struct A<F> { f: F, } // Implements new and do_something impl<F> A<F> where F: Fn() { fn new(f: F) -> A<F> { A { f: f

我尝试从为结构
a
实现的
do\u something
调用一个闭包。我读了一些关于这个的帖子,但我现在有点迷路了。以下是一个简化版本:

// A simple structure
struct A<F> {
    f: F,
}

// Implements new and do_something
impl<F> A<F> where F: Fn() {
    fn new(f: F) -> A<F> {
        A { f: f }
    }
    fn do_something(&self) {
        self.f() // Error is here.
    }
}

fn main() {
    let a = A::new( || println!("Test") );
    a.do_something()
}
//一个简单的结构
结构A{
f:f,
}
//实现新功能并做一些事情
impl A,其中F:Fn(){
fn新(f:f)->A{
A{f:f}
}
fn做某事(&self){
self.f()//此处有错误。
}
}
fn main(){
设a=a::new(| | println!(“Test”);
a、 做某事
}
它显示此错误:

错误:在当前作用域中找不到类型
&A
的名为
f
的方法

我以为有人叫闭包,但我好像错过了什么。我试图用
self.f.call()
(没有真正理解的随机测试)替换
self.f()
,但它说明了两件事:

  • 错误:此函数接受1个参数,但提供了0个参数
  • 错误:显式使用unbox闭包方法
    调用
    是实验性的[E0174]
  • 我不确定第一个错误是什么,但我想如果这是实验性的,我现在就不会使用这个功能


    有没有方法在方法中调用闭包?

    将成员名称括在括号中:

    fn do_something(&self) {
        (self.f)()
    }
    
    如果我没记错的话,根本原因与解析代码时的优先级有关
    self.f()
    查找名为
    f
    的方法,并将失败,因为该方法不存在
    (self.f)(
    导致对其进行不同的解析,特别是查找成员变量。

    第二个错误是这里的一个问题,未绑定的闭包很难处理。您需要将闭包装箱(将其放在指针后面),因为闭包可能有各种奇怪的大小

    编辑:正如Shepmaster指出的,这部分是不正确的。我将扩展下面的旧答案,因为它在处理闭包和传递闭包时可能会有所帮助

    (另外,
    call
    是实验性的,在这种情况下没有必要,所以我们不需要这样做)

    最后,你可以叫它了,对吗

    fn do_something(&self) {
        self.f() // Rust being silly
    }
    
    但是Rust编译器仍然希望在这里调用一个方法,而不是我们的闭包字段。因此,我们明确地取消对方框的引用:

    fn do_something(&self) {
        (*self.f)() // Explain our intentions to the confused compiler
    }
    
    现在,它起作用了!但是我们需要间接的方法吗?我想是的,但似乎不是(谢谢谢普)!你看,
    A
    结构已经是泛型的,因此它的大小应该适合任何单个
    F
    类型。因此,我们不需要间接,可以使用旧的定义:

    struct A<F> {
        f: F,
    }
    

    因此,这似乎只是Rust编译器在调用语法方面的一个语法限制。

    这不是我的问题:/无论如何,谢谢!闭包具有奇怪大小的要点是准确的,但是编译器知道闭包的大小,因此可以避免装箱。您也不需要显式取消引用该框来调用它-
    box
    实现
    Deref
    。因此,
    (self.f)(
    在装箱时同样有效。
    fn do_something(&self) {
        (*self.f)() // Explain our intentions to the confused compiler
    }
    
    struct A<F> {
        f: F,
    }
    
    fn do_something(&self) {
        (self.f)() // Explicitly access a struct member, then call it
    }