函数定义
函数定义
函数参数
函数也可以被定义为拥有 参数(parameters
参数声明
fn main() {
say_hi("ruster");
}
fn say_hi(name: &str) {
println!("Hi, {}", name);
}
在函数签名中,必须 声明每个参数的类型。这是
fn main() {
another_function(5, 6);
}
fn another_function(x: i32, y: i32) {
println!("The value of x is: {}", x);
println!("The value of y is: {}", y);
}
将函数作为参数
在
fn main() {
let xm = "xiaoming";
let xh = "xiaohong";
say_what(xm, hi);
say_what(xh, hello);
}
fn hi(name: &str) {
println!("Hi, {}.", name);
}
fn hello(name: &str) {
println!("Hello, {}.", name);
}
fn say_what(name: &str, func: fn(&str)) {
func(name)
}
上例中,
函数返回值
函数可以向调用它的代码返回值。我们并不对返回值命名,但要在箭头(->)后声明它的类型。在
fn five() -> i32 {
5
}
fn main() {
let x = five();
println!("The value of x is: {}", x);
}
在 five
函数中没有函数调用、宏、甚至没有 let
语句——只有数字 5
。这在-> i32
。尝试运行代码;输出应该看起来像这样:
$ cargo run
Compiling functions v0.1.0 (file:///projects/functions)
Finished dev [unoptimized + debuginfo] target(s) in 0.30 secs
Running `target/debug/functions`
The value of x is: 5
five
函数的返回值是 5
,所以返回值类型是 i32
。让我们仔细检查一下这段代码。有两个重要的部分:首先,let x = five();
这一行表明我们使用函数的返回值初始化一个变量。因为 five
函数返回 5
,这一行与如下代码相同:
let x = 5;
其次,five
函数没有参数并定义了返回值类型,不过函数体只有单单一个 5
也没有分号,因为这是一个表达式,我们想要返回它的值。
Unit
在
fn main() {
//statements
}
之前有说过,函数的返回值类型是在参数列表后,加上箭头和类型来指定的。不过,一般我们看到的
fn main() -> () {
//statements
}
For historical reasons and convenience, the tuple type with no elements (()) is often called ‘unit’ or ‘the unit type’.
返回值
下面来看一个有返回值的例子:
fn main() {
let a = 3;
println!("{}", inc(a));
}
fn inc(n: i32) -> i32 {
n + 1
}
上面的例子中,函数 inc
有一个 i32
类型的参数和返回值,作用是将参数加inc
函数中只有 n+1
一个表达式,并没有像return
语句类返回一个值。这是因为,与其他基于语句的语言(如
return
关键字,不过一般用于提前返回。来看一个简单地例子:
fn main() {
let a = [1,3,2,5,9,8];
println!("There is 7 in the array: {}", find(7, &a));
println!("There is 8 in the array: {}", find(8, &a));
}
fn find(n: i32, a: &[i32]) -> bool {
for i in a {
if *i == n {
return true;
}
}
false
}
上例中,find
函数,接受一个 i32
类型 n
和一个 i32
类型的切片slice
a
,返回一个bool
值,若true
,否则返回 false
。可以看到,return
关键字,用在for
循环的if
表达式中,若此时find
函数最后一句 false
改为 return false;
(注意分号不可省略)也是可以的,不过这就不是for
循环中的 i
,其类型为 &i32
,需要使用解引用操作符来变换为 i32
类型。
返回多个值
fn main() {
let (p2,p3) = pow_2_3(789);
println!("pow 2 of 789 is {}.", p2);
println!("pow 3 of 789 is {}.", p3);
}
fn pow_2_3(n: i32) -> (i32, i32) {
(n*n, n*n*n)
}
可以看到,上例中,
发散函数
发散函数(diverging function)是!
作为返回类型表示:
fn main() {
println!("hello");
diverging();
println!("world");
}
fn diverging() -> ! {
panic!("This function will never return");
}
由于发散函数不会返回,所以就算其后再有其他语句也是不会执行的。倘若其后还有其他语句,会出现编译警告。其中 panic!
是一个宏,使当前执行线程崩溃并打印给定信息。返回类型 !
可用作任何类型:
let x: i32 = diverges();
let y: String = diverges();