和C++不同的是,函数可以被当成头等公民被复制到一个值中,这个值可以像返回一样被调用
fn main() {
let tup = (1, 2);
let fun = add1; //fn类型:fn((i32, i32))->i32
let x = fun(tup); // 局部变量func 可以被当成普通函数一样被调用
println!("x = {}", x);
}
fn add1(t:(i32, i32))->i32{
return t.0 + t.1; //语句;并不会返回值,因此return显示指定
}
rust中,每个函数都有自己单独的类型
fn main() {
let mut fun = add1; //fn类型:fn((i32, i32))->i32
fun = add3; //error[E0308]: mismatched types
}
fn add1(t:(i32, i32))->i32{
return t.0 + t.1;
}
fn add3(t:(i32, i32))->i32{
return t.0 + t.1;
}
fn main() {
let tup = (1, 2);
let mut fun:fn((i32, i32))->i32 = add1; //fn类型
println!("x = {}", fun(tup));
fun = add3;
println!("x = {}", fun(tup));
fun = add2;
println!("x = {}", fun(tup));
}
fn add1(t:(i32, i32))->i32{
return t.0 + t.1;
}
fn add3(t:(i32, i32))->i32{
return t.0 + t.1;
}
fn add2((x, y):(i32, i32))->i32{
x + y
}
方法2:使用as类型转换【去掉参数就是类型】
fn main() {
let tup = (1, 2);
let mut fun = add1 as fn((i32, i32))->i32;
println!("x = {}", fun(tup));
fun = add3;
println!("x = {}", fun(tup));
fun = add2;
println!("x = {}", fun(tup));
}
fn add1(t:(i32, i32))->i32{
return t.0 + t.1;
}
fn add3(t:(i32, i32))->i32{
return t.0 + t.1;
}
fn add2((x, y):(i32, i32))->i32{
x + y
}
备注:上面的这两种方法都不能修改参数类型或者返回值类型不同的情况,比如
fn main() {
let tup = (1, 2);
let mut fun = add1 as fn((i32, i32))->i32;
fun = add2; //error[E0308]: mismatched types
}
fn add1(t:(i32, i32))->i32{
return t.0 + t.1;
}
fn add2(x:i32)->i32{
x
}
在Rust的函数体内运行定义其他item,比如静态变量,常量,函数,trait,类型,模块等等
fn main() {
static INNER_STATIC:i64 = 42;
//函数体内定义函数
fn internal_incre(x:i64)->i64{
x+1
}
struct InnerStruct(i64);
impl InnerStruct{
fn incre(&mut self){
self.0 = internal_incre(self.0)
}
}
let mut t = InnerStruct(INNER_STATIC);
t.incre();
println!("{}", t.0)
}
当一些item仅在此函数体内有用时,可以把它们直接定义在函数体内,以免污染外部的命名空间。
当一个函数不能正常返回时,可以定义它的返回类型是!,这种函数叫做发散函数
fn diverge() ->!{
panic!("the function never return!")
}
fn main() {
let x:i32 = diverge();
let y:String = diverge();
}
!又叫做发散类型,发散类型可以转换为任何类型
let p = if x > 0{
panic!("error")
}else{
100;
};
if-else每条分支的类型必须一致
在Rust中,有以下这些情况永远不会返回,它们的类型就是!。
fn main() {
test(11, 11.1);
}
fn test(x:i32, y:f32){
println!("hello world!, x = {}, y = {}", x, y);
}
1、参数是特殊变量,是函数签名的一部分
2、在函数签名中,必须 声明每个参数的类型
3、当一个函数有多个参数时,使用逗号分隔
4、println!中的!表示这是一个宏而不是一个函数,Rust中的宏可以理解为一种安全版的编译器语法扩展。这里之所以适用宏而不是函数,是因为标准输出宏可以完成编译器格式检查,更加安全
函数体由一系列语句和一个可选的结尾表达式构成
fn main() {
let x = 3; //语句:没有返回值,因此不能用来赋值
//let y = (let x = 3); //error: let x = 3语句并不返回值,所以没有可以绑定到y上的值
//let y = (x = 3); //error
let y = x + 1;
let z = {
let x = 3;
x + 1
};
print!("{},{}", y, z);
// let z = {
// let x = 3;
// return x + 1; //error[E0308]: mismatched types
// };
}
1、表达式的结尾没有分号。如果在表达式的结尾加上分号,它就变成了语句,而语句不会返回值
2、Rust表达式分为"左值"和”右值“两类。所谓左值,就是这个表达式可以表达一个内存地址,因此它们可以放到赋值运算符左边使用。其他的都是右值
fn main() {
let tup = (1, 2);
let x = add1(tup);
println!("x = {}", x);
let x = add2(tup);
println!("x = {}", x);
}
fn add1(t:(i32, i32))->i32{
return t.0 + t.1; //语句;并不会返回值,因此return显示指定
}
fn add2((x, y):(i32, i32))->i32{
x + y //函数的返回值等同于函数体最后一个表达式的值
}
1、在 Rust 中,函数的返回值等同于函数体最后一个表达式的值。使用 return 关键字和指定值,可从函数中提前返回;但大部分函数隐式的返回最后的表达式
可以通过元组来返回多个值
fn main() {
let (x, y) = test1(11);
println!("x = {}, y = {}", x, y);
}
fn test1(x:i32)->(i32, i32){
return (x + 1, x + 2); //语句;并不会返回值,因此return显示指定
}
可以使用结构体来返回多个值
标准库中的 std::env::args()可以获取命令行传递的参数
fn main() {
for arg in std::env::args() {
println!("Arg: {}", arg);
}
std::process::exit(0)
}
如何获取环境变量
。。。
函数可以用const关键字修饰,这样的函数在编译阶段就被编译器执行,返回值也被视为编译起常量。
const fn cube(num:usize)->usize{
num * num * num
}
fn main() {
const DIM:usize = cube(2); //常量不能类型推导, 常量的值必须是编译器间就能确定的常量
const ARR:[i32;DIM] = [0; DIM];
println!("{:?}", ARR) //[0, 0, 0, 0, 0, 0, 0, 0]
}