C# ?? Ruby 中的运算符?

Posted

技术标签:

【中文标题】C# ?? Ruby 中的运算符?【英文标题】:C# ?? operator in Ruby? 【发布时间】:2010-10-31 11:50:09 【问题描述】:

是否可以实施? Ruby 中的运算符?

a = nil
b = 1

x = a ?? b # x should == 1
x = b ?? 2 # x should == 1

【问题讨论】:

【参考方案1】:

coalesce gem 离你最近的地方。

nil || 5 # => 5
false || 5 # => 5 :(
false._? 5 # => false :)

【讨论】:

【参考方案2】:
x = b || 2

它(C# 中的??)称为合并运算符。

【讨论】:

由于我在回答中概述的原因,这不起作用。尝试在示例中将 b 设置为 false。【参考方案3】:

在 Ruby 中,短路布尔运算符(||&&andor)不返回 truefalse,而是返回确定结果的第一个操作数整个表达式。这行得通,因为 Ruby 有一个相当简单的真理概念。或者更确切地说,它有一个相当简单的虚假概念:nil 是虚假的,显然false 是虚假的。 其他的一切都是真的。

所以,由于|| 在其至少一个 操作数为真时为真,并且操作数从左到右计算,这意味着a || b 返回a,当@ 987654333@ 是真的。但是当a为假时,表达式的结果只依赖于b,从而返回b

这意味着,因为nil 为假,您可以只使用|| 而不是?? 作为您提供的示例。 (还有漂亮的a ||= b 运算符,类似于a || a = b,但不完全一样。)

但是,only 有效,因为您没有在示例中使用布尔值。如果您希望处理布尔值,那将是行不通的:

b = false

x = b || 2 # x should be == false, but will be 2

在这种情况下,您将不得不使用#nil? 和一个条件表达式:

b = false

x = unless b.nil? then b else 2 end # x should be == 2

或使用三元条件运算符:

b = false

x = b.nil? ? 2 : b # x should be == false

如果你愿意,你可以用一个很好的方法把它包装起来:

class Object
  def _? b = nil
    return self
  end
end

class NilClass
  def _? b = nil
    return yield if block_given?
    return b
  end
end

b = false

x = b._?  2  # x should be == false
x = b._? 2 # x should be == false

这个可爱的 sn-p 是由多态性、开放类和 nil 实际上是一个代表虚无的对象这一事实带来的(不像,比如说,Java,null 实际上什么都没有)。

【讨论】:

a ||= b 与其说是“某种”a || a = b,倒不如说是a = a || b。不是条件赋值,赋值总会发生。 @Theo:这就是 ISO Ruby 语言规范的当前草案所说的,但这是错误的。 MRI、YARV、JRuby、Rubinius、XRuby、MacRuby、IronRuby、Ruby.NET、MagLev、SmallRuby、tinyrb、RubyGoLightly 和所有其他 Ruby 实现,将其实现为短路条件赋值。 Ruby 编程语言(由 matz 自己共同编写)、Programming Ruby 和所有其他 Ruby 书籍都以这种方式记录了它。 RubySpec 测试套件以这种方式对其进行测试。 *** 上的几个讨论和 ruby​​-talk 上的几十个讨论都是这样说的。马茨自己也是这么说的。 peter cooper 文章的必填链接:rubyinside.com/…【参考方案4】:

您正在寻找条件赋值:

a ||= b  # Assign if a isn't already set

和 ||运营商

a = b || 2 # Assign if b is assigned, or assign 2

【讨论】:

由于我在回答中概述的原因,这不起作用。尝试在第一个示例中将 a 设置为 false,或者在第二个示例中将 b 设置为 false。 正确,@JörgWMittag。谨防真假! 另外我很确定你不能用 ?? 得到一个“不能分配给 nil”的错误。但是你可以在 object 和 NilClass 上编写一个方法 ifNil 来评估一个块,就像在 smalltalk 中一样

以上是关于C# ?? Ruby 中的运算符?的主要内容,如果未能解决你的问题,请参考以下文章

Ruby 中的“=~”运算符是啥?

erb中的Ruby三元运算符?

Ruby,Splat 的源代码?

(一元)* 运算符在这段 Ruby 代码中做了啥?

Ruby中And/&&的运算符优先级[重复]

为啥在 Ruby 中构建字符串时,铲子运算符 (<<) 优于加号 (+=)?