2.3 函数

[root@itoracle src]# cargo new functions
Created binary (application) `functions` package
[root@itoracle src]# cd functions/
[root@itoracle functions]# vim src/main.rs

Rust code uses snake case as the conventional style for function and variable names. In snake case, all letters are lowercase and underscores separate words. Here’s a program that contains an example function definition:

fn main() {
println!("Hello, world!"); another_function();
} fn another_function() {
println!("Another function.");
}

Rust doesn’t care where you define your functions, only that they’re defined somewhere.

[root@itoracle functions]# cargo run
Compiling functions v0.1.0 (/usr/local/automng/src/goapp/src/functions)
Finished dev [unoptimized + debuginfo] target(s) in 6.41s
Running `target/debug/functions`
Hello, world!
Another function.

函数参数

In function signatures, you must declare the type of each parameter. This is a deliberate decision in Rust’s design: requiring type annotations in function definitions means the compiler almost never needs you to use them elsewhere in the code to figure out what you mean.

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);
}
[root@itoracle functions]# cargo run
Compiling functions v0.1.0 (/usr/local/automng/src/goapp/src/functions)
Finished dev [unoptimized + debuginfo] target(s) in 3.03s
Running `target/debug/functions`
The value of x is: 5
The value of y is: 6

函数体

Function bodies are made up of a series of statements optionally ending in an expression.

We’ve actually already used statements and expressions. Statements are instructions that perform some action and do not return a value. Expressions evaluate to a resulting value. Let’s look at some examples.

Creating a variable and assigning a value to it with the let keyword is a statement. let y = 6; is a statement.

fn main() {
let y = 6;
}

Function definitions are also statements; the entire preceding example is a statement in itself.

Statements do not return values. Therefore, you can’t assign a let statement to another variable, as the following code tries to do; you’ll get an error:

fn main() {
let x = (let y = 6);
}
[root@itoracle functions]# cargo run
Compiling functions v0.1.0 (/usr/local/automng/src/goapp/src/functions)
error: expected expression, found statement (`let`)
--> src/main.rs:2:14
|
2 | let x = (let y = 6);
| ^^^ expected expression
|
= note: variable declaration using `let` is a statement error: aborting due to previous error error: Could not compile `functions`. To learn more, run the command again with --verbose.

The let y = 6 statement does not return a value, so there isn’t anything for x to bind to.

Expressions evaluate to something and make up most of the rest of the code that you’ll write in Rust. Consider a simple math operation, such as 5 + 6, which is an expression that evaluates to the value 11.Expressions can be part of statements: The 6 in the statement let y = 6; is an expression that evaluates to the value 6. Calling a function is an expression. Calling a macro is an expression. The block that we use to create new scopes, {}, is an expression, for example

fn main() {
let _x = 5; let _y = {
let _x = 3;
_x + 1
}; println!("The value of y is: {}", _y);
}
let y = {
let x = 3;
x + 1
};

is a block that, in this case, evaluates to 4. That value gets bound to y as part of the letstatement. Note the x + 1 line without a semicolon at the end, which is unlike most of the lines you’ve seen so far. Expressions do not include ending semicolons. If you add a semicolon to the end of an expression, you turn it into a statement, which will then not return a value. Keep this in mind as you explore function return values and expressions next.

[root@itoracle functions]# cargo run src/main.rs
Compiling functions v0.1.0 (/usr/local/automng/src/goapp/src/functions)
Finished dev [unoptimized + debuginfo] target(s) in 0.63s
Running `target/debug/functions src/main.rs`
The value of y is: 4

函数返回值

We don’t name return values, but we do declare their type after an arrow (->). In Rust, the return value of the function is synonymous with the value of the final expression in the block of the body of a function. You can return early from a function by using the return keyword and specifying a value, but most functions return the last expression implicitly. Here’s an example of a function that returns a value:

fn five() -> i32 {
5
} fn main() {
let x = five(); println!("The value of x is: {}", x);
}
[root@itoracle functions]# cargo run
Compiling functions v0.1.0 (/usr/local/automng/src/rust/test/functions)
Finished dev [unoptimized + debuginfo] target(s) in 4.96s
Running `target/debug/functio

There are two important bits: first, the line let x = five(); shows that we’re using the return value of a function to initialize a variable. Because the function five returns a 5, that line is the same as the following:

let x = 5;

Second, the five function has no parameters and defines the type of the return value, but the body of the function is a lonely 5 with no semicolon because it’s an expression whose value we want to return.

fn main() {
let x = plus_one(5); println!("The value of x is: {}", x);
} fn plus_one(x: i32) -> i32 {
x + 1
}

注意,函数体结束的时候没有分号“;”

[root@itoracle functions]# cargo run
Compiling functions v0.1.0 (/usr/local/automng/src/rust/test/functions)
Finished dev [unoptimized + debuginfo] target(s) in 1.76s
Running `target/debug/functions`
The value of x is: 6

如果不是在函数体最后一行返回,则可以使用return语句

fn main() {
let mut x = plus_one(5);
println!("The value of x is: {}", x);
x = plus_one(15);
println!("The value of x is: {}", x);
} fn plus_one(mut x: i32) -> i32 {
if x < 10 {
return 10;
}
x = x + 10;
x
}
[root@itoracle functions]# cargo run
Compiling functions v0.1.0 (/usr/local/automng/src/rust/test/functions)
Finished dev [unoptimized + debuginfo] target(s) in 1.22s
Running `target/debug/functions`
The value of x is: 10
The value of x is: 25

另外,最后一句使用return语句也是可以的,但rust建议使用不加分号的表达式

fn main() {
let mut x = plus_one(5);
println!("The value of x is: {}", x);
x = plus_one(15);
println!("The value of x is: {}", x);
} fn plus_one(mut x: i32) -> i32 {
if x < 10 {
return 10;
}
x = x + 10;
return x;
}
[root@itoracle functions]# cargo run
Compiling functions v0.1.0 (/usr/local/automng/src/rust/test/functions)
Finished dev [unoptimized + debuginfo] target(s) in 2.43s
Running `target/debug/functions`
The value of x is: 10
The value of x is: 25

 没有返回值的函数

fn justgo(){
println!("永远是多远?");
}
[root@itoracle functions]# cat src/main.rs
fn main() {
let mut x = plus_one();
println!("The value of x is: {}", x);
x = plus_one();
println!("The value of x is: {}", x);
justgo();
} fn plus_one(mut x: i32) -> i32 {
if x < {
return ;
}
x = x + ;
x
} fn justgo(){
println!("永远是多远?");
}

运行结果

[root@itoracle functions]# cargo run
Compiling functions v0.1.0 (/usr/local/automng/src/rust/test/functions)
Finished dev [unoptimized + debuginfo] target(s) in .95s
Running `target/debug/functions`
The value of x is:
The value of x is:
永远是多远?

函数定义后,必须被调用,不然运行时会给出警告

warning: function is never used: `justgo`
--> src/main.rs::
|
| fn justgo(){
| ^^^^^^^^^^^ Finished dev [unoptimized + debuginfo] target(s) in .48s
Running `target/debug/functions`

使用元组让函数返回多个值

fn testFnReturn() -> (u8,String){
(,"good".to_string())
}
let a = testFnReturn();
println!("{}",a.);

最新文章

  1. glade2支持C++代码的输出(3)
  2. 常用的不熟的sql语句
  3. source insight shift+tab问题
  4. PAIP.并发编程 多核编程 线程池 ExecutorService的判断线程结束
  5. 使用GoodFeaturesToTrack进行关键点检测---29
  6. javascript 遍历object对象
  7. 句柄(handle)
  8. iOS之设置状态栏颜色
  9. 【动态规划】【二分】【最长上升子序列】Vijos P1028 魔族密码
  10. OD: Heap Overflow (XP SP2 - 2003) &amp; DWORD SHOOT via Chunk Resize
  11. 九度oj 1482:玛雅人的密码
  12. C语言做一个通讯录程序(在console里面运行)
  13. linux驱动: 如何向模块传递参数, module_param和module_param_array
  14. 几种经典的数据排序及其Java实现
  15. Android程序检测网络是否可用
  16. 了解HTML/HTML5中的download属性
  17. Vuejs实例-02Vue.js项目集成ElementUI
  18. (转)volatile关键字
  19. 使用 Cglib 实现多重代理
  20. timestamp 与 nonce 防止重放攻击

热门文章

  1. winform combobox绑定数据
  2. 服务机器人的小脑——SLAM技术
  3. 学会使用postman工具模拟请求-----待补充
  4. input 输入框两种改变事件的方式
  5. ipa包使用命令上传fir.im或者蒲公英
  6. 输入框获取焦点后placeholder文字消失、修改placeholder的样式
  7. 英文操作系统中中文乱码(SQL中 NVARCHAR 和 VARCHAR区别)
  8. C#多线程 线程嵌套调用问题
  9. poj3167(kmp)
  10. SP34096 DIVCNTK - Counting Divisors (general)(Min_25筛)