我正在阅读Rust文档,并遇到了以下示例和声明
使用return作为函数的最后一行有效,但被认为是糟糕的样式:
fn foo(x: i32) -> i32 {
if x < 5 { return x; }
return x + 1;
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以写上面的内容
fn foo(x: i32) -> i32 {
if x < 5 { return x; }
x + 1
}
Run Code Online (Sandbox Code Playgroud)
但我更倾向于写前者,因为这更直观.我确实理解函数返回值应该用作表达式,以便后面有效但是为什么不鼓励前者呢?
Chr*_*gan 20
它就是.
公约不需要特别好的理由,它们只需要是普遍接受的惯例.事实上,这个确实有一个相对较好的理由 - 因为你没有return和它一样短;.您可能认为这return x + 1;更直观,但我强烈反对 - 它真的很棒,我觉得有必要修复它.我说这是一个在开始使用Rust之前从未使用过面向表达式语言的人.在编写Python的时候,return x + 1在那个地方看起来是对的,在编写Rust时看起来不对.
现在,碰巧应该编写代码:
fn foo(x: i32) -> i32 {
if x < 5 {
x
} else {
x + 1
}
}
Run Code Online (Sandbox Code Playgroud)
这强调了语言的表达方向.
mja*_*mja 16
从reddit复制:为什么 return 语句的语法不明确?
来自@pcwalton 的回答
显式返回在闭包中真的很烦人。例如,在引入 ES6 箭头函数之前,这是 JavaScript 的一大痛点
Run Code Online (Sandbox Code Playgroud)myArray.map(function(x) { return x * 2; })即使没有
function关键字,它也非常冗长。一旦你在你的语言中的某个地方有隐式返回,为了一致性起见,你最好在任何地方都有它们。它使代码不那么冗长这一事实只是一个额外的好处。
Rust 是一种面向表达式的语言。一个块的形式
Run Code Online (Sandbox Code Playgroud){ stmt; stmt; ... stmt; expr }这些语句(基本上)是表达式或
let绑定,()如果未指定,则尾随表达式是隐式的。整个块的值就是最后一个表达式的值。这不仅适用于函数。你可以写
Run Code Online (Sandbox Code Playgroud)let foo = if x { y } else { z };so
if也取代了 C 的?:运算符。每种块都以相同的方式工作:Run Code Online (Sandbox Code Playgroud)let result = unsafe { let y = mem::transmute(x); y.frob() };所以函数末尾的隐式返回是 Rust 面向表达式语法的自然结果。改进的人体工程学只是一个很好的奖励:)
谜题:
return x本身就是一种表达——它的价值是什么?答案(由@dubiousjim 建议):
它是一个 never 类型
!。
Clippy lint 给出了以下needless_returnlint 的原理:
去掉回车和分号会让代码更加生疏。
这可能是我们所能得到的最好的客观理由。
就直觉而言;我觉得它是由我们的个人经历决定的,因此是主观的。虽然 Rust 本身并不是一种函数式编程语言,但许多使用和开发它的人似乎对 Haskell 等完全基于表达式的函数式编程语言有很强的背景。在 Rust 的许多领域(例如错误处理)都可以强烈感受到这种影响。因此,对于他们(说实话,包括我自己)来说,使用表达式而不是声明似乎更优雅。
我强烈怀疑它源自函数式编程风格。(根据@Markus Klein 的回答)。
你的例子,在 OCaml 中:
let foo x = if x < 5 then x else x + 1
Run Code Online (Sandbox Code Playgroud)
与您在 Rust 中修改的示例进行比较:
fn foo(x: i32) -> i32 {
if x < 5 { x } else { x + 1 }
}
Run Code Online (Sandbox Code Playgroud)
OCaml 中的闭包示例:
fun x -> if x < 5 then x else x + 1
Run Code Online (Sandbox Code Playgroud)
与 Rust 闭包相比:
|x| if x < 5 { x } else { x + 1 }
Run Code Online (Sandbox Code Playgroud)
所以Rust似乎采用了函数式编程风格。
为什么函数式编程语言要这样做?我不知道。
可能是因为return当代码中的含义已经很清楚时,到处乱扔 ' 会很烦人并且毫无意义。
函数式编程语言并不真正依赖于经典的“分配给变量,操作变量,返回变量”范例,而是使用“分配给变量,通过几个不同的函数管道变量,最终结果是输出”范例(并且甚至分配给变量也是可选的:搜索“无点编程”)。
Rust 中的“经典”范例示例:
fn qux(mut x: i32) -> i32 {
x = foo(x);
x = bar(x);
return x; // classic C style
}
Run Code Online (Sandbox Code Playgroud)
与 OCaml 中的函数式编程范例对比:
let qux x = x |> foo |> bar
Run Code Online (Sandbox Code Playgroud)
如果我们在 OCaml 示例中要求 a,return我们需要将其放在最开始,这在很大程度上是没有意义的,因为我们已经知道它将返回什么。
因此,出于上述原因,这种函数式编程风格可能会延续到 Rust。
例子:
Rust 的if语句计算结果为表达式,与 C(“经典”)和 OCaml(函数式)不同。