rust1.82 为什么能编译代码片段A
,而不能编译代码片段B
?
代码片段A
let config= match config_option {
None => &Config::default(),
Some(config) => config,
};
代码片段B
let config = config_option.unwrap_or_else(|| &Config::default());
1
共 6 条评论, 1 页
评论区
写评论感谢如此详细的回复。
--
👇
LazyQc: 首先,片段B在任何类似语言里都不应该是被认为有效可行的,因为它返回了一个函数(闭包)内的本地变量的引用,在函数返回后其变量就会被销毁,所以rust会阻止这种写法,这应该属于引用/指针的最基础规定了。
其次,片段A属于rust对表达式的一种友好支持(即extending based on expression,看上一个评论) 通俗的讲
&Config::default()
可以分成两步:Config::default()
创建一个匿名变量(不能显式可见,但栈上会如变量一般分配位置),再返回其引用,rust规定了其有效作用域跟随其接收的变量,即这里绑定了config
变量生命周期,在该生命周期失效后,原“匿名变量”才会被销毁。书写错误。由于不知道怎么表示修改痕迹,因此直接修订成最后结果了
--
👇
Joe-Alwyn:
代码A是&Config::default(),代码B是&ConsoleLoggingConfig::default(),类型不一样
首先,片段B在任何类似语言里都不应该是被认为有效可行的,因为它返回了一个函数(闭包)内的本地变量的引用,在函数返回后其变量就会被销毁,所以rust会阻止这种写法,这应该属于引用/指针的最基础规定了。
其次,片段A属于rust对表达式的一种友好支持(即extending based on expression,看上一个评论) 通俗的讲
&Config::default()
可以分成两步:Config::default()
创建一个匿名变量(不能显式可见,但栈上会如变量一般分配位置),再返回其引用,rust规定了其有效作用域跟随其接收的变量,即这里绑定了config
变量生命周期,在该生命周期失效后,原“匿名变量”才会被销毁。extending-based-on-expressions
临时变量生命周期的问题,我的理解是,第一个case中,你match创建的临时变量走的临时变量的特殊规则,可以提升其生命周期保证引用的有效。
第二次case就是普通的一个函数返回内部创建变量的引用的规则,这是肯定不可能正确的。
代码A是&Config::default(),代码B是&ConsoleLoggingConfig::default(),类型不一样