tetu式

ゲームと音楽・作曲の自己満足と悩みどころの多いプログラムのブログ。

Swiftの===は厳密比較ではない

一応前回の続きです。

今回もあまり見かけない演算子に触れてみます。



===

今回は比較演算子について。
if文の中にあったり、参考演算子で使ったりするやつですね。

class A {
    var numA = 0;
}

var classA = A()
var classAA = A()

print(classA === classAA)  // false

classAA = classA

print(classA === classAA)  // true

イコールを三つ重ねた演算子について。
phpだと厳密比較という意味で用いられますね。


phpは == が曖昧比較(1 == "1" は型が違うがtrueになる)ですが、
=== を使うことで()内の結果がfalseになります。


swiftでは === の両辺がオブジェクトの時に使える比較演算子です。
通常のInt型とかString型とかの変数でこの比較を行うとエラーになります。

var numA = 10
var numB = "10"

print(numA == numB)  // エラー


そもそもswiftの == 演算子は型が違う時点でエラーを起こすので
キャストしないといけないのですが・・・


で、オブジェクトって何なのかというと端的に言えばクラスのことです。
まだクラスについては本ブログで触れていませんでしたが、また別の機会に。


===は両辺が同じオブジェクトを示している場合はtrueが返るようになってます。
じゃあ1回目も2回目もprintでの結果はtrueになるのでは?と思いがちですが・・・


この辺りはクラスの記事を作る時に詳しく調べるつもりですが、
最初のクラスの宣言(インスタンス生成)のclassAとclassAAは
別々の領域に確保されたオブジェクトであるため、falseになります。


classAA = classA の処理を入れることで完全に同一のオブジェクトとなり、
結果がtrueになります。


また、 == の反対が != であるように === の反対は !== になります。

~=

この演算子を使うことで右辺の内容が左辺にあるならtrueになります。
パターンマッチングってやつですね。

print(1...10 ~= 6)  // true
print(1...10 ~= 6.5)  // true
print(1...10 ~= "10")  // エラー
print(1...10 ~= 0.99)  // false
print("a"..."z" ~= "g")  // true
print("a"..."z" ~= "G")  // false
print("a"..."z" ~= "aAzZ")  // true
print("a"..."z" ~= "AaZz")  // false


このパターンマッチングですが・・・数値についてはまだ良しとして
文字列の場合はちょっと厄介ですね。


数値の場合はStringでなければ型を自動でキャストしてくれるみたいで
1〜10の範囲でなら小数点をつけても判定してくれました。


しかし文字の方は・・・上二つは分かりますが下二つは謎です。
最初の1文字部分だけ判定してるのかな?
そもそも文字の範囲を指定する時点であまり使い方として
よろしく無い気もしますが・・・

文字の方については別の機会に詳しく調べてみましょ。


あとこの比較演算子は左辺と右辺の役割が別々になっているので
順序を逆にするとエラーになります。