为啥带赋值的三元运算符不返回预期的输出?

Posted

技术标签:

【中文标题】为啥带赋值的三元运算符不返回预期的输出?【英文标题】:Why doesn't a ternary operator with assignment return the expected output?为什么带赋值的三元运算符不返回预期的输出? 【发布时间】:2013-06-29 05:20:18 【问题描述】:

我想知道为什么使用三元运算符的赋值会产生奇怪的反应:

a = "foo"­
=> "foo"
a = nil ? nil : a
=> "foo"
a
=> "foo"

但是:

a = nil ? nil : a
=> "foo"
a = "bar"­ ? "bar"­ : a
=> "bar"
a
=> "bar"

和:

if a = nil
  puts "should be nil"
end
=> nil

不会puts 字符串,因为a = nil 将返回nil 因此为false,尽管分配成功。

这一切都像预期的那样吗?

【问题讨论】:

“分配成功”似乎是这里的关键误解。赋值表达式的结果是(并且应该是)赋值,而不是赋值是否“成功”。 (实际上变量赋值不会真的失败。) 在这个例子中,我没有混淆赋值和比较,好的,如果我赋值我会得到值赋值混淆清除关于那个thx给你们所有人但是为什么我的第一个仍然是“foo”三元运算符的示例虽然我分配了 nil ? 你的第一个例子应该读作a = (nil ? nil : a)。由于 nil 是“falsey”,因此您将之前的 a 值分配给 a,即 "foo" 所以(a = nil)? nil : a 会返回我的期望值,非常感谢 ;) 【参考方案1】:
if a = nil

这不是返回 false,而是返回分配的内容,在本例中为 nilnil 是“假的”,所以这就是为什么它没有进入 puts

至于为什么:

a = "foo"­
=> "foo"
a = nil ? nil : a
=> "foo"
a
=> "foo"

这是因为你又分配了anil ? nil : a 返回 a 这就是分配的内容。所以a = nil ? nil: a 最终会被解释为a = a

【讨论】:

【参考方案2】:

我相信这一点:

if a = nil

应该是:

if a == nil

单个= 表示赋值,a = nilnil 赋值给a 并因此评估为nil,这是错误的。这就是为什么执行没有进入puts 部分,而== 表示相等测试。

除此之外,您发现代码中有什么奇怪的地方?毕竟这是正常行为。

【讨论】:

【参考方案3】:

假设您打算将 a = nil 用作分配并且知道这不是比较,则无论成功与否都不会返回。

它返回分配的值,即nil

【讨论】:

【参考方案4】:

您提供的示例符合预期。

也许您将赋值运算符= 与比较运算符== 混淆了。试试最后一段这样的代码:

if a == nil
  puts "should be nil"
end
=> nil
> a
=> "bar"

【讨论】:

【参考方案5】:
a = "foo"­
# => "foo"
a = nil ? nil : a
# => "foo"
a
# => "foo"

为了解释上面的内容,我将从这个开始 - “Ruby 中的每件事都是一个对象,除了块;Ruby 中的所有对象都有一个真值,除了 nilfalse。”因此,在您上面的代码部分中,a = nil ? nil : a 表达式将被评估为a = a。这就是为什么'foo'has been returned as a value ofa`。

a = "bar"­ ? "bar"­ : a
# => "bar"
a
# => "bar"

正如我刚才所说,除了nilfalse 之外,所有对象都有真实值,“bar”总是true。所以表达式a = "bar"­ ? "bar"­ : a 将被评估为a = "bar"

if a = nil
  puts "should be nil"
end
=> nil

与我上面解释的if a = nil 部分的解释相同。所以由于false控制没有进入if子句主体,并返回nil

【讨论】:

以上是关于为啥带赋值的三元运算符不返回预期的输出?的主要内容,如果未能解决你的问题,请参考以下文章

为啥要使用三元运算符而不为“真”条件赋值 (x = x ?: 1)

三元运算符为啥以及何时返回左值?

Javascript 三元运算符和赋值

为啥在三元运算符中使用“0”会返回第一个值?

javascript:使用三元运算符的意外评估行为

C# - 为啥我不能在字符串中使用三元运算符? [复制]