22

Ruby ではをInteger === 5返しますtrue。同様にをString === "karthik"返しますtrue
ただし、5 === Integer返品しますfalse。そして"karthik" === String
演算子が可換でないのはなぜですか?

4

4 に答える 4

37

簡単な答えは、意味がないからです。演算子が記述する関係は可換ではありません。なぜ演算子はそうでなければならないのですか?

あなた自身の例を見てください: 5is an Integer. しかしInteger5ですか?それはどういう意味ですか?

===は、場合の包含演算子であり、包含は交換されません。

ケースの包含演算子が等号を使用し、通常はトリプル イコールthreequalsまたはcase equality演算子と呼ばれるという事実は、等値とはまったく関係がないだけでなく、多くの法則にも準拠していないため、非常に残念です。等式は、推移性や交換性などに準拠しています。

についての私の怒りの詳細については、===参照してください

于 2010-12-24T21:45:06.740 に答える
7

非常に単純な理由の 1 つは、is_a?クラスの関係が交換可能ではないということです。両方のオペランドがクラスである場合を考えてみましょう:

Class === String

これは true を返しますString.is_a?(Class)。ただしString === Class、 false を返します。これClass.is_a?(String)は false であり、当然のことです。

もう 1 つの理由は、 のセマンティクスが===左側のオペランドに依存することです。これにも 2 つの理由があります: a) ruby​​ では、セマンティクスは常に左オペランドに依存します。なぜなら、左オペランドはメソッド呼び出しのレシーバーだからです。意図したセマンティクスを持つステートメント。

于 2010-12-24T16:17:41.607 に答える
2

多くの演算子は可換ではありません。

===、分岐がケースである場合に呼び出されるため、「ケース等価演算子」と呼ばれます。

次のことが便利で便利です。

foo = 42
case foo
when Integer
  # branches here
when String
  # etc...
end

だったらあまり役に立たない

foo = Integer
case foo
when 42
# would branch here??
when 666
# etc...
end

Ruby 1.9 では、===Proc/lambda の演算子はその Proc を呼び出すことに注意してください。

divisible_by_three = ->(x){x % 3 == 0}
divisible_by_three === 42 # => true

繰り返しますが、caseステートメントでは非常に便利ですが、逆の順序ではあまり役に立ちません。

于 2010-12-24T18:01:02.007 に答える
1

case-when比較を実装する必要があります

非可換演算子があるのは普通のことです。

/ - % [] . -> ^ << >> < <= > >= && || = += -= ,

そしてたまたま、部分的に case-when演算子===として存在します。これは Ruby ではかなり手の込んだものであり、可換演算に単純化する必要がある場合、そうはなりません。

于 2010-12-24T17:56:20.207 に答える