windows rustdesk服务器设置账户 rust服务器main
开发环境
- Windows 10
- Rust 1.52.1
- VS Code 1.56.2
Rust的函数
函数在Rust代码中无处不在。如该语言中最重要的函数之一:main函数,它是许多程序的入口点。 同时还有fn关键字,它允许您声明新函数。如下列:
fn main() { println!("Hello, world!"); test(); } fn test() { println!("Another function."); }上面有一个主函数:main()和另外一个函数test()。
函数定义
Rust中的函数定义从fn开始,在函数名后面有一组括号。花括号告诉编译器函数体从哪里开始和结束。如下面定义的test函数。
fn test() { println!("Another function."); }函数调用
我们可以通过输入函数名和一组括号来调用定义的任何函数。 因为test是在程序中定义的,所以可以从main函数内部调用它。如上面main函数调用test函数。
fn main() { println!("Hello, world!"); test(); }函数参数
函数也可以具有参数,参数是作为函数签名一部分的特殊变量。 当一个函数有参数时,可以为这些参数提供具体的值。 从技术上讲,具体值被称为参数,但在日常对话中,人们倾向于在函数定义中的变量或调用函数时传入的具体值中交替使用parameter和argument
下面是test函数的重写版本,显示了Rust中的参数:
fn main() { test(5); } fn test(x: i32) { println!("The value of x is: {}", x); }test函数有一个参数为x的形参。x的类型被指定为i32。 当5被传递给另一个函数时,println!宏把5放在格式字符串中一对花括号的地方。
在函数签名中,必须声明每个形参的类型。 在Rust的设计中,这是一个经过深思熟虑的决定:在函数定义中要求类型注释意味着编译器几乎不需要您在代码的其他地方使用它们来理解您的意思。
当函数需要多个参数时,用逗号分隔参数声明,如:
fn main() { test(5, 6); } fn test(x: i32, y: i32) { println!("The value of x is: {}", x); println!("The value of y is: {}", y); }编译运行下
cargo run结果
函数体
函数体由一系列语句(可选地以表达式结尾)组成。 到目前为止,我们只讨论了没有结束表达式的函数,但是已经有作为语句一部分的表达式。 因为Rust是一种基于表达的语言,这是一个需要理解的重要区别。 其他语言没有相同的区别,所以让我们看看什么是语句和表达式,以及它们的差异如何影响函数体。
我们实际上已经用过语句和表达式了。 语句是执行某些操作但不返回值的指令。
使用let关键字创建变量并为其赋值是一条语句。 如:
fn main() { let y = 6; }函数定义也是语句; 前面的整个示例本身就是一个语句。
语句不返回值。 因此,不能像下面的代码所尝试的那样,将let语句赋给另一个变量; 你会得到一个错误:
fn main() { let x = (let y = 6); }编译上面的代码
let y = 6语句没有返回值,所以没有任何东西可以让x绑定。 这与C和Ruby等其他语言中不同,在这些语言中,赋值返回赋值的值。 在这些语言中,x = y = 6 x和y的值都是6; 但在Rust中却不是这样。
表达式的计算结果是某些东西,并且构成了Rust中编写的大部分其余代码。 考虑一个简单的数学操作,例如5 + 6,这是一个计算值为11的表达式。 表达式可以是语句的一部分:在上述例子中,语句let y = 6中的6; 是一个计算值为6的表达式。 调用函数是一个表达式。 调用宏是一个表达式。 我们用来创建新作用域的块{}是一个表达式, 如:
fn main() { let x = 5; // 块代码,将x赋值为3,接着将3 + 1也就是4赋值给y let y = { let x = 3; x + 1 // 注意这里没有分号 }; println!("The value of y is: {}", y); }请注意末尾没有分号的x + 1行,这与目前看到的大多数行不同。 表达式不包括结束分号,如果在表达式的末尾添加分号,则将其转换为一个语句,该语句将不返回值。 在接下来研究函数返回值和表达式时,请记住这一点。
带有返回值的函数
->)之后声明它们的类型。 在Rust中,函数的返回值与函数体块中最终表达式的值是同义的。 通过使用return关键字并指定值,可以提前从函数返回,但大多数函数都会隐式返回最后一个表达式。 如:
fn five() -> i32 { 5 } fn main() { let x = five(); println!("The value of x is: {}", x); }在函数five()中没有函数调用、宏,甚至没有let语句——只有数字5本身。 这在Rust中是完全有效的函数。 注意,函数的返回类型也被指定了,是-> i32。
函数five()中的5是函数的返回值,这就是为什么返回类型是i32。 让我们更详细地研究这个问题。 这里有两个重要的位:第一行,let x = five(); 说明我们正在使用函数的返回值来初始化变量。 因为函数five返回5,所以这一行与下面相同:
let x = 5;其次,函数five()没有形参,并且定义了返回值的类型,但是函数体是一个没有分号的单独的5,因为它是一个我们想要返回值的表达式。
函数示例
下面我们看下函数的示例,这里还是沿用上次工程rust-demo。
代码如下:
fn main() { let x = plus_one(5); println!("The value of x is: {}", x); } fn plus_one(x: i32) -> i32 { x + 1 // 将传入参数的值+1,并返回 }编译运行
cargo run运行结果
本章重点
- 函数定义
- 函数返回值