0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

go で構造体を比較したい時に、気軽に== を使って比較する前に、ポインタ型か、そうでないかをちゃんと確認しようね。

Last updated at Posted at 2021-09-04

golang における 「==」 の特性

golang における「==」 は、基本的には対象の同一性をみてtrue/false の判断をする。

ただ、比較する対象がポインタ型でない場合は同値性で判断してくれることもある

例えば
https://play.golang.org/p/E1Fty3pkKYI

package main

import (
	"fmt"
)

func main() {
	nameA := FullName{"ヤマダ", "太郎"}
	nameB := FullName{"ヤマダ", "太郎"}
	nameC := FullName{"吉田", "太郎"}

	fmt.Println(nameA == nameB)  // true
	fmt.Println(nameA == nameC) // false
}

type FullName struct {
	FirstName string
	LastName  string
}

このように、nameA, B, C にはFullName 型が入っており、その中に入れられたfirstName, LastName を比較してtrue/false をみてくれる

ポインタ型の比較

一方で、ポインタ型を使った時の比較はどうか?

package main

import (
	"fmt"
)

func main() {
	nameA := NewFullName("ヤマダ", "太郎")
	nameB := NewFullName("ヤマダ", "太郎")
	fmt.Println(nameA == nameB) //false
}

type FullName struct {
	FirstName string
	LastName  string
}

func NewFullName(FirstName, LastName string) *FullName {
	return &FullName{
		FirstName,
		LastName,
	}
}

FullName型 のポインタ型を返却するNewFullName を使用して作成した値を比較すると比較対象の同一性を確認するようになる。
もちろん格納されているアドレスが異なるため、false になる
だが、NewFullName という関数からはポインタ型を返却することが読み取れないため、"ヤマダ", "太郎" という値が一致していることを期待して比較を行うと、意図せずfalse を返却する処理になってしまう。

結論

golang の比較は基本的には同一性の比較になっていることを忘れないように。
もしどうしても同値性で比較を行いたいのであれば、reflect.DeepEqual を使用すること。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?