是否可以实施? Ruby 中的运算符?
a = nil
b = 1
x = a ?? b # x should == 1
x = b ?? 2 # x should == 1
在 Ruby 中,短路布尔运算符(
||
、&&
、and
和 or
)不返回 true
或 false
,而是返回决定整个结果的第一个操作数表达。这是可行的,因为 Ruby 对真理有一个相当简单的想法。或者更确切地说,它有一个相当简单的虚假概念:nil
是假的,并且显然false
是假的。 其他一切都是真的。
因此,当
至少有一个的操作数为 true 时
||
为 true,并且操作数从左到右计算,这意味着当 a || b
为 true 时,a
返回 a
。但当 a
为 false 时,则表达式的结果仅依赖于 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
这个可爱的片段是通过多态性、开放类以及
nil
实际上是一个对象 代表虚无这一事实带来的(不像 Java,其中 null
is 实际上什么也没有)。
您正在寻找条件作业:
a ||= b # Assign if a isn't already set
和||操作员
a = b || 2 # Assign if b is assigned, or assign 2
x = b || 2
它(C# 中的
??
)称为合并运算符。
有 coalesce 宝石,这是您能得到的最接近的宝石。
nil || 5 # => 5
false || 5 # => 5 :(
false._? 5 # => false :)
Ruby 有一个空合并运算符
&.
,称为“安全导航运算符”:
irb(main):004:0> a = nil
=> nil
irb(main):005:0> a&.foo
=> nil
irb(main):006:0> a = Struct.new(:foo).new(foo: 3)
=> #<struct foo=3>
irb(main):007:0> a&.foo
=> 3