読者です 読者をやめる 読者になる 読者になる

きくらげ観察日記

好きなことを、適当に。

Gaucheで値の比較

値の比較に使用する関数は通常eq?, eqv?, equal?の3種類あるのですが、それらの使い分けが曖昧だったのでまとめてみました。

eq?

(eq? x y) はxとyが全く同じオブジェクトであるか(=メモリ上の同じ位置にあるか)どうかを判定します。Pythonのisに近いやつですね。

gosh> (eq? 1 1) ; 数値の比較結果は処理系依存らしい。Gaucheでは#tになる?
#t
gosh> (eq? "hoge" "hoge")
#f
gosh> (define x "hoge")
x
gosh> (eq? x x)
#t
gosh> (eq? 3.14 3.14)
#f

eqv?

(eqv? x y) はxとyの型と値が等しければ#tを返します。ただし、ここでいう「値の比較」はかなりプリミティブというかCよりのものであるので、複雑なデータ構造はたとえ同等の内容を表していても#fになります。たぶんあたりは意図どおりに比較できるはずです。

gosh> (eqv? 3.14 3.14)
#t
gosh> (eqv? #\A #\A)
#t
gosh> (eqv? "A" "A")
#f
gosh> (eqv? '(3 . #\x) '(3 . #\x))
#f

equal?

equal? はユーザーがカスタマイズできる同値比較で、object-equal?メソッドをオーバーライドすることによって振る舞いを決定できます。多くのデータ型は意図したとおりに値の比較を行ってくれます。

gosh> (equal? (list 3 2 1) (iota 3 3 -1))
#t
gosh> (equal? "hoge" (string-append "ho" "ge"))
#t