2017-11-08 8 views
1

私のアプリケーションで使用される "セット"のgormタイプを作成したいと思います。だから私は、フラグなどのキーと空のstructs{}としての私のタイプgorm.DBmapを定義したいと思います:map [gorm.DB] struct {} {}は無効なマップキータイプgorm.DBを与えます

var (
    autoMigrations map[gorm.DB]struct{} 
) 

しかし、コンパイラは、私がエラーでこれを行うことはできません:invalid map key type gorm.DB。私は次のようにgorm.DB Sへのポインタを使用して、それをだますことができます。

map[*gorm.DB]struct{} 

しかし、私はそれを一意にする必要があり、私のマップがdb.AutoMigrate(&Chat{})のように満たされます場合、私は別のアドレスに類似したオブジェクトの多くを得ることができるので、それは、解決策はありません。

別の解決策は、gorm.DBのスライスにすることです:

autoMigrations []gorm.DB 

をしかし、私は非常識少し思われる、手動で追加の要素をフィルタリングする必要があります。

答えて

1

comparableのマップでは、タイプをキーとして使用できます。 Spec: Map types:

The comparison operators == and != must be fully defined for operands of the key type; thus the key type must not be a function, map, or slice.

gorm.DB構造体であり、構造体の値は、すべてのフィールドが同等である場合にのみ匹敵する:

Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non- blank fields are equal.

しかし、例えばgorm.DBありマップタイプであるDB.valuesフィールドは類似していないので、gorm.DBの値は比較できないため、マップキーとして使用することはできません。

タイプのセットを作成する場合は、reflect.Typeをマップキーとして使用し、そのタイプの値からreflect.TypeOf()を使用して取得できます。あなたが問題の型の値を作成することなくreflect.Typeをしたい場合は

少しトリックは、あなたが(nilであってもよい)、その型のポインタ値から開始し、reflect.Type記述子を取得するためにType.Elem()を使用することができます尖ったタイプの。例えば

、実際Pointた/作成することなく、構造体型Point struct{ X, Y int }reflect.Typeディスクリプタを取得する:main.Pointを印刷し

type Point struct{ X, Y int } 
tpoint := reflect.TypeOf((*Point)(nil)).Elem() 
fmt.Println(tpoint) 

を。 Go Playgroundで試してみてください。

How can I prevent a type being used as a map key?

Why can't Go slice be used as keys in Go maps pretty much the same way arrays can be used as keys?

Set of structs in Go

+1

優秀な答え:

は、関連の質問を参照してください!独自の比較機能を定義するにはどうすればよいですか? Pythonの '__hash__'と同じですか?このように私はそれらを比較可能にすることができます。 –

+1

@EugeneLisitskyいいえ、そうではありません。 Goランタイムによって自動的に使用されるカスタムコンパレータ関数を記述することはできません。 – icza

関連する問題