文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
5.1 定义
使用 fn
定义,参数和返回值须标注类型。
- 以逗号分隔多个参数。
- 以
->
指示返回值类型。 - 以元组返回多个值。
- 以
Result<T, E>
返回正确或错误值。
- 支持函数嵌套(nested)。
- 支持匿名函数和闭包(closure)。
- 不支持重载(overload)。
- 不支持变参(以 macro 实现)。
- 不支持默认值(以
Option<T>
实现)。
可用 return
提前返回,或以表达式作为结束。
隐式返回最后一个表达式值。执行流的最后一行,不一定是函数代码的最后一行。即便没有返回值定义,也隐式返回
unit
。
函数定义的参数为形参,调用时传递的是实参。多数语言实现上,将实参(argument)复制为形参(parameter)。形参等同于函数内部定义的变量,但内存位置未必在该函数栈帧内。优先使用寄存器传输。超出则由调用方提供形参和返回值内存,以
RDI/RSI
传递地址。
fn add(x: i64, y: i64) -> i64 { if x < 0 { return -1; } let z = x + y; z // 不能以分号结束,那就成了语句。 } fn main() { assert_eq!(add(-10, 2), -1); assert_eq!(add(1, 2), 3); }
fn set(mut x: i64) { // 形参 x 可变: let mut x x = 200; } fn main() { let x = 0i64; set(x); }
fn inc(x: &mut i64) { // 可变引用: 目标可变。 *x += 1; } fn main() { let mut x = 10i64; inc(&mut x); assert_eq!(x, 11); }
函数是第一类对象。可赋值,或作为参数或返回值。
fn add(x: i32, y: i32) -> i32 { x + y } fn main() { let f: fn(i32, i32) -> i32; f = add; assert_eq!(f(1, 2), 3); }
type F = fn(i32, i32) -> i32; // 别名,更易读和维护! fn test() -> F { fn add(x: i32, y: i32) -> i32 { x + y } return add; } fn main() { let add = test(); assert_eq!(add(1, 2), 3); }
参数默认值
利用 Option<T>
实现参数默认值。
有
Some(T)
和None
两个成员。可用is_none
、is_some
等方法进行判断。
fn inc(x: Option<i32>) -> i32 { // 完整方式。 let a = match x { Some(v) => v, None => 100, // 默认值 }; a + 1 } fn main() { assert_eq!(inc(Some(123)), 124); assert_eq!(inc(None), 101); }
fn inc(x: Option<i32>) -> i32 { // 简略方式。 let a = x.unwrap_or(100); a + 1 }
fn inc(x: Option<i32>) -> i32 { if let Some(a) = x { return a + 1 } 101 }
多返回值
以元组打包需要返回的多个值。
fn test() -> (i32, f32) { (1, 1.2f32) } fn main() { let (i, f) = test(); assert_eq!(i, 1); assert_eq!(f, 1.2f32); }
还可以用 Result<T, E>
实现类似 Golang (result, error)
返回值。
包含
Ok
、Err
两个成员。有关错误处理,详见后续章节。
fn test(x: i32) -> Result<i32, &'static str> { match x { x if x > 0 => Ok(1), _ => Err("error"), } } fn main() { let r = test(-1); match r { Ok(v) => println!("ok: {:?}", v), Err(e) => println!("err: {:?}", e), } }
嵌套函数
嵌套函数无法使用外层变量。
用闭包实现该功能。
fn main() { let x = 1; fn test() { println!("{}", x); ^ can't capture dynamic environment in a fn item } test(); }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论