Are functions in Rust first class objects?

2019-06-15 15:43发布

Can functions be passed as arguments? For example, in JavaScript you can pass a function as an argument like this:

setInterval(function() { /*...*/ }, 1000);

标签: rust
3条回答
地球回转人心会变
2楼-- · 2019-06-15 16:37

They are first class. In contrast to JavaScript, Rust has two types - functions and closures.

fn first_class() {
    println!("function");
}

fn higher_kinded<F: FnOnce()>(cb: F) {
    cb();
}

fn main() {
    higher_kinded(first_class); // passing function
    higher_kinded(|| println!("closure")); // passing closure
}
查看更多
Fickle 薄情
3楼-- · 2019-06-15 16:38

Anonymous functions like function() {} in JavaScript do exist in Rust, and you can define them using the closure syntax

|arg, arg2, arg3| {
  /* function body including optionally closed-over variables */
} 

Notice that the argument and return types are inferred!

Whether they are first class or not demands a little more exploration. By default, closed-over variables will be borrowed by the function. You can specify that those values be moved into the function using a move closure:

let num = 5;
let plus_num = move |x: i32| x + num;

Importantly, closures that do not reference their environment, which includes move closures, do not require references to the stack frame that created them. Since their sizes aren't known, they aren't first class objects by themselves.

You can Box a closure and return it as a trait object of the Fn trait.

This answer a brief summary of what's in the book which explains how closures are desugared and how they interact with the environment.

查看更多
放荡不羁爱自由
4楼-- · 2019-06-15 16:44

It seems that it is the case, as described in the reference manual.

fn add(x: int, y: int) -> int {
  return x + y;
}

let mut x = add(5,7);

type Binop<'a> = |int,int|: 'a -> int;
let bo: Binop = add;
x = bo(5,7);

It also tried the following, which pass a closure and function in the same way:

fn myproc(val: int) {
    println!("{}", val*10);
}

fn call_func(func: |int| -> ()) {
    func(3);
}

…
call_func(|x| {println!("{}", x)});
call_func(myproc);
查看更多
登录 后发表回答