为什么我们不能覆盖`||`和`&&`?

Aru*_*hit 10 ruby keyword

David A. Black在他的书中说:

[T]他有条件赋值运算符||=,以及它很少发现表弟&& =,两者都提供相同类型的快捷方式的pseudooperator方法,但都是基于运营商,即||和&&,你不能覆盖.

他为什么特别提到我们不能覆盖||和&&?

Lin*_*ios 12

与对象上的其他运算符不同,逻辑上可以依赖于类的行为,布尔运算符是语言的一部分.当你有一个类似的运算符时==,可以合理地说这个运算符的行为取决于对象的类型.字符串应该逐字符检查,键值元组的哈希键值元组等等.但是,行为&&和||基于语言的真假定义,而不是任何特定于对象的定义.如果语言允许您覆盖这些运算符,则可能没有一致的布尔模型,并且这些运算符将变得完全无用.

此外,还有性能考虑因素.因为&&并且||是短循环运算符,这意味着如果第一个参数,例如&&,评估为false,则第二个参数甚至永远不会被评估.有了||,如果第一个计算结果为真,二是从来不评价.如果您可以覆盖这些运算符,则无法执行此行为,因为Ruby运算符会作为方法重载.在调用方法之前,必须根据定义评估所有参数.因此,失去了性能提升和短路操作器的编程便利性.

  • 完全可以在Ruby(或任何具有第一类过程的语言)中实现惰性求值:只需将表达式包装在lambda内进行延迟求值.Ruby*确实*有lambda,甚至更好但它有*blocks*.在Ruby中实现条件运算符作为消息发送肯定是可能的.我实际上只是为了好玩而做到了. (2认同)