|
|
|
@ -1,6 +1,6 @@
|
|
|
|
|
# 闭包上奇怪的生命周期
|
|
|
|
|
|
|
|
|
|
Rust一道独特的靓丽风景就是生命周期,也是反复折磨新手的最大黑手,就连老手,可能一不注意就会遇到一些生命周期上的陷阱,例如闭包上使用引用。
|
|
|
|
|
Rust 一道独特的靓丽风景就是生命周期,也是反复折磨新手的最大黑手,就连老手,可能一不注意就会遇到一些生命周期上的陷阱,例如闭包上使用引用。
|
|
|
|
|
|
|
|
|
|
## 一段简单的代码
|
|
|
|
|
先来看一段简单的代码:
|
|
|
|
@ -23,7 +23,7 @@ error: lifetime may not live long enough
|
|
|
|
|
|
|
|
|
|
咦?竟然报错了,明明两个一模一样功能的函数,一个正常编译,一个却报错,错误原因是编译器无法推测返回的引用和传入的引用谁活得更久!
|
|
|
|
|
|
|
|
|
|
真的是非常奇怪的错误,学过[Rust生命周期](https://github.com/sunface/rust-course/blob/main/src/advance/lifetime/basic.md)的读者应该都记得这样一条生命周期消除规则: **如果函数参数中只有一个引用类型,那该引用的生命周期会被自动分配给所有的返回引用**。我们当前的情况完美符合,`function`函数的顺利编译通过,就充分说明了问题。
|
|
|
|
|
真的是非常奇怪的错误,学过[Rust生命周期](https://course.rs/advance/lifetime/basic.html)的读者应该都记得这样一条生命周期消除规则: **如果函数参数中只有一个引用类型,那该引用的生命周期会被自动分配给所有的返回引用**。我们当前的情况完美符合,`function`函数的顺利编译通过,就充分说明了问题。
|
|
|
|
|
|
|
|
|
|
那为何闭包就出问题了?
|
|
|
|
|
|
|
|
|
@ -100,9 +100,9 @@ let closure_slision = |x: &i32| -> &i32 { x };
|
|
|
|
|
|
|
|
|
|
编译器就必须深入到闭包函数体中,去分析和推测生命周期,复杂度因此极具提升:试想一下,编译器该如何从复杂的上下文中分析出参数引用的生命周期和闭包体中生命周期的关系?
|
|
|
|
|
|
|
|
|
|
由于上述原因(当然,实际情况复杂的多),Rust语言开发者其实目前是有意为之,针对函数和闭包实现了两种不同的生命周期消除规则。
|
|
|
|
|
由于上述原因(当然,实际情况复杂的多), Rust 语言开发者其实目前是有意为之,针对函数和闭包实现了两种不同的生命周期消除规则。
|
|
|
|
|
|
|
|
|
|
## 总结
|
|
|
|
|
虽然我言之凿凿,闭包的生命周期无法解决,但是未来谁又知道呢。最大的可能性就是之前开头那种简单的场景,可以被自动识别和消除。
|
|
|
|
|
|
|
|
|
|
总之,如果有这种需求,还是像古天乐一样做一个平平无奇的男人,老老实实使用函数吧.
|
|
|
|
|
总之,如果有这种需求,还是像古天乐一样做一个平平无奇的男人,老老实实使用函数吧。
|