C# ?? Ruby中的运算符?

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

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

你正在寻找有条件的分配:

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

和|| 操作者

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

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

所以,因为|| 当其至less一个操作数为真,并且操作数从左到右计算时,这是真实的,这意味着a || ba为真时, a || b返回a 。 但是,如果a是假的,则expression式的结果完全依赖于b ,因此b被返回。

这意味着,因为nil是假的,你可以使用|| 而不是?? 对于你给的例子。 (也有一个漂亮的a ||= b运算符,它的作用类似于a || a = b ,但不完全相同。)

但是, 这只适用于你的例子,因为你不使用布尔值。 如果你期望处理布尔值,那将是行不通的:

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

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

 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 

这个可爱的代码片段由多态性,开放类和nil实际上是一个代表虚无的对象(不像Java说的, null实际上什么也没有)这个事实。

 x = b || 2 

它(在C#中?? )被称为coalesce操作符。

有凝聚的gem,这是尽可能接近你会得到。

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