I'm a beginner studying Rust.
I'd like to create a function that receives structural methods, but I can't pass them to the function, so please give me some advice.
Tried
Receive Function - Rust by Example
http://doc.rust-jp.rs/rust-by-example-ja/fn/closures/input_functions.html
I created the following code by referring to .
structure Foo{
s —String,
}
impl Foo {
fn method(&self,s:&String){
println!("{},s);
}
}
fn function(s:&String) {
println!("{},s);
}
fn execute<F> (f:F, s:&String)
where
F: Fn(&String),
{
f(s);
}
US>fnmain(){
lets=String::from("function!");
execute(function, & s);
// >> function!
lets=String::from("method!");
let foo=Foo{s};
execute(foo.method, & foo.s);
// >>>
}
Results
execute(function,&s);
is running, but the following error appears in the execute(foo.method,&foo.s);
section:
error [E0615]: attempted to take value of method `method` on type `Foo`
-->src/main.rs:35:15
|
35 | execute (foo.method, & foo.s);
| ^^^^^^ method, not a field
|
help —use parents to call the method
|
35 | execute(foo.method(_), & foo.s);
| +++
However, what you want to do is not execute(foo.method(&foo.s);
to "pass the return value of the method to the function."
How do I pass the structural method to a function?
Thank you for your cooperation.
If you specify a closure, you can do what you want (although the amount of description increases).
execute(|x|foo.method(x), & foo.s);
If you want to pass the function itself:
However, since the method
function takes two arguments: self
and s
, the function that receives the method needs to be modified.
fn execute2<F>(f:F, foo:&Foo, s:&String)
where
F: Fn(&Foo, & String),
{
f(foo,s);
}
execute2(Foo::method, & foo, & foo.s);//->method!
There is another problem with the code you are asking, besides execute(foo.method, & foo.s)
.Let's fix it in order.
First, the argument for the execute
function f:F
, but
// Take only one & String as argument
F: Fn(&String),
This is the Fn(&String)
type.This is a closure that takes only one argument.
However, the method
method in Foo
has the following definition and takes two arguments:
impl Foo{
// take two arguments: self: & Foo and s: & String
fn method(&self,s:&String){
The method
is of type Fn(&Foo,&String)
and cannot be passed to the argument f
(type Fn(&String)
for the execute
function.
Let's fix this first.
In the first place, Foo
has the field s:String
, so you do not need to take another s
as an argument, such as fn method(&self, s:&String)
.Make the following changes:
before change
impl Foo{
// take two arguments: self: & Foo and s: & String
fn method(&self,s:&String){
println!("{},s);
}
}
modified
impl Foo{
// Take only one self:&Foo argument
US>fn method (&self) {
// use fields s
println!("{},self.s);
}
}
The method
is now of the Fn(&Foo)
type with only one argument.
Then modify the execute
function.Change the second argument s:&String
to accept any type T
.
fn execute<F,T>(f:F,t:&T)
where
F: Fn(&T),
{
f(t);
}
This allows you to take both the method
of type Fn(&Foo)
and the function
of type Fn(&String)
as arguments.
Finally, let's correct the code below that was originally an error.
execute(foo.method, & foo.s);
Rust's method is only one of the related functions. If foo
is of type Foo
, you write foo.method()
, the compiler assumes that Foo::method(&foo)
.Therefore, you can write as follows.
// Foo method as first argument and & Foo as second argument
execute(Foo::method, & foo);
You will now be able to compile.The results are as follows:
$cargo run
function!
method!
The overall code is as follows:
structure Foo{
s —String,
}
impl Foo {
US>fn method (&self) {
println!("{},self.s);
}
}
fn function(s:&String) {
println!("{},s);
}
fn execute<F,T>(f:F,t:&T)
where
F: Fn(&T),
{
f(t)
}
US>fnmain(){
lets=String::from("function!");
execute(function, & s);
// >> function!
lets=String::from("method!");
let foo=Foo{s};
execute(Foo::method, & foo);
// >> method!
}
© 2024 OneMinuteCode. All rights reserved.