Methods 如何在Rust中将方法用作函数指针

Methods 如何在Rust中将方法用作函数指针,methods,types,rust,function-pointers,traits,Methods,Types,Rust,Function Pointers,Traits,我有一个trait方法,它需要改变结构的内部数据,我希望我可以将setter方法作为参数传递给trait方法。我希望这样做,以便通过指定作为参数传递的函数,灵活处理发生变化的内容 这段代码是我试图做的一个简化,它有同样的编译器问题 谢谢 代码 struct MyStruct { i: usize } impl MyStruct { fn set_i(mut self, i: usize) -> Self { self.i = i; self

我有一个trait方法,它需要改变结构的内部数据,我希望我可以将setter方法作为参数传递给trait方法。我希望这样做,以便通过指定作为参数传递的函数,灵活处理发生变化的内容

这段代码是我试图做的一个简化,它有同样的编译器问题

谢谢

代码

struct MyStruct {
    i: usize
}

impl MyStruct {
    fn set_i(mut self, i: usize) -> Self {
        self.i = i;
        self
    }
    fn new() -> Self{
        MyStruct{ i: 0 }
    }
}

trait MyTrait {
    fn do_some_setting(&mut self, setter_function: fn(&mut Self, usize) -> Self ) {
        setter_function(&mut self, 7);
    }
}

impl MyTrait for MyStruct {}


fn main() {
    let mut s = MyStruct::new()
                .set_i(3);
                
    assert_eq!(s.i, 3);
    
    s.do_some_setting(MyStruct::set_i);
    
    assert_eq!(s.i, 7);
}
问题

error[E0308]: mismatched types
  --> src/main.rs:27:23
   |
27 |     s.do_some_setting(MyStruct::set_i);
   |                       ^^^^^^^^^^^^^^^ expected `&mut MyStruct`, found struct `MyStruct`
   |
   = note: expected fn pointer `for<'r> fn(&'r mut MyStruct, _) -> MyStruct`
                 found fn item `fn(MyStruct, _) -> MyStruct {MyStruct::set_i}`
错误[E0308]:类型不匹配
-->src/main.rs:27:23
|
27 | s.do_一些设置(MyStruct::set_i);
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^应为“&mut MyStruct”,找到结构“MyStruct”`
|
=注意:MyStruct需要fn指针``
找到fn项`fn(MyStruct,0;)->MyStruct{MyStruct::set_i}`

这不起作用,因为
MyTrait::do_some_setting
要求函数的第一个参数类型为
&mut Self
,而
MyStruct::set_i
的第一个参数类型为
mut Self

您可以通过将
MyStruct::set_i
的签名更改为
set_i(&mut self,i:usize)
来解决此问题,但是编译器会抱怨
类型不匹配
,因为它希望
MyStruct::set_i
返回
self
,但您将返回
&mut self
。您可以派生
克隆
并在克隆后返回结构,也可以将签名中的返回类型更改为
&mut Self

编译器将再次抱怨类型不匹配,因为
MyTrait::do\u中的
setter\u函数
中的某些设置
是返回
Self
的函数,而不是
&mut Self
。您必须更改
setter\u函数的签名
以返回
&mut Self

编译器现在会抱怨在
让mut s=MyStruct::new().set_i(3)
处借用时删除了
临时值。您必须先创建
MyStruct
,然后在其上使用
set\i

最后,您将得到如下代码:

struct MyStruct{
i:使用,
}
impl MyStruct{
fn集合_i(&mut self,i:usize)->&mut self{
self.i=i;
自己
}
fn new()->Self{
MyStruct{i:0}
}
}
性状我的性状{
fn do_一些设置(&mut self,setter_函数:fn(&mut self,usize)->&mut self){
setter_函数(self,7);
}
}
MyStruct{}的impl MyTrait
fn main(){
让mut s=MyStruct::new();
s、 第i组(3);
断言(s.i,3);
s、 做一些设置(MyStruct::set\u i);
断言(s.i,7);
}

这不起作用,因为
MyTrait::do_some_setting
要求函数的第一个参数类型为
&mut Self
,而
MyStruct::set_i
的第一个参数类型为
mut Self

您可以通过将
MyStruct::set_i
的签名更改为
set_i(&mut self,i:usize)
来解决此问题,但是编译器会抱怨
类型不匹配
,因为它希望
MyStruct::set_i
返回
self
,但您将返回
&mut self
。您可以派生
克隆
并在克隆后返回结构,也可以将签名中的返回类型更改为
&mut Self

编译器将再次抱怨类型不匹配,因为
MyTrait::do\u中的
setter\u函数
中的某些设置
是返回
Self
的函数,而不是
&mut Self
。您必须更改
setter\u函数的签名
以返回
&mut Self

编译器现在会抱怨在
让mut s=MyStruct::new().set_i(3)
处借用时删除了
临时值。您必须先创建
MyStruct
,然后在其上使用
set\i

最后,您将得到如下代码:

struct MyStruct{
i:使用,
}
impl MyStruct{
fn集合_i(&mut self,i:usize)->&mut self{
self.i=i;
自己
}
fn new()->Self{
MyStruct{i:0}
}
}
性状我的性状{
fn do_一些设置(&mut self,setter_函数:fn(&mut self,usize)->&mut self){
setter_函数(self,7);
}
}
MyStruct{}的impl MyTrait
fn main(){
让mut s=MyStruct::new();
s、 第i组(3);
断言(s.i,3);
s、 做一些设置(MyStruct::set\u i);
断言(s.i,7);
}