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 中,短路布尔运算符(||
、&&
、and
和 or
)不返回 true
或 false
,而是返回确定结果的第一个操作数整个表达式。这行得通,因为 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 中的运算符?的主要内容,如果未能解决你的问题,请参考以下文章