構造体を定義します...
type Session struct {
playerId string
beehive string
timestamp time.Time
}
空のセッションを割り当てることがあります(nilが不可能なため)
session = Session{};
次に、空かどうかを確認します。
if session == Session{} {
// do stuff...
}
明らかにこれは機能していません。どうやって書くの?
すべてのフィールドが 比較可能 であるため、==を使用してゼロ値の複合リテラルと比較できます。
if (Session{}) == session {
fmt.Println("is zero value")
}
構文解析のあいまいさ のため、if条件の複合リテラルの周りに括弧が必要です。
上記の==
の使用は、すべてのフィールドが 比較可能 である構造体に適用されます。構造体に比較不可能なフィールド(スライス、マップ、または関数)が含まれている場合、フィールドを1つずつゼロ値と比較する必要があります。
値全体を比較する代わりに、有効なセッションでゼロ以外の値に設定する必要があるフィールドを比較することもできます。たとえば、有効なセッションでプレーヤーIDが!= ""でなければならない場合、次を使用します。
if session.playerId == "" {
fmt.Println("is zero value")
}
さらに3つの提案またはテクニックがあります。
追加のフィールドを追加して、構造体にデータが入力されているか空かを確認できます。 ready
のゼロ値はempty
であるため、bool
ではなくfalse
という名前を意図的に付けました。したがって、Session{}
its ready
フィールドは自動的にfalse
になり、真実がわかります。構造体はまだ準備ができていない(空になっている)ということです。
type Session struct {
ready bool
playerId string
beehive string
timestamp time.Time
}
構造体を初期化するとき、ready
をtrue
に設定する必要があります。 ready
フィールド自体をテストするだけなので、isEmpty()
メソッドはもう必要ありません(必要に応じて作成できます)。
var s Session
if !s.ready {
// do stuff (populate s)
}
この1つの追加bool
フィールドの重要性は、構造体が大きくなるにつれて、または比較できないフィールド(スライス、map
および関数値など)が含まれる場合に増加します。
これは以前の提案と似ていますが、構造体が空でない場合にinvalidと見なされる既存のフィールドのゼロ値を使用します。これの使いやすさは実装に依存します。
たとえば、あなたの例でplayerId
を空のstring
""
にできない場合、次のようにそれを使用して構造体が空かどうかをテストできます。
var s Session
if s.playerId == "" {
// do stuff (populate s, give proper value to playerId)
}
この場合、このチェックは実装に依存するため、このチェックをisEmpty()
メソッドに組み込む価値があります。
func (s Session) isEmpty() bool {
return s.playerId == ""
}
そしてそれを使用して:
if s.isEmpty() {
// do stuff (populate s, give proper value to playerId)
}
2番目の提案は、構造体へのポインターを使用することです:*Session
。ポインターはnil
値を持つことができるため、テストすることができます。
var s *Session
if s == nil {
s = new(Session)
// do stuff (populate s)
}
reflect.deepEqual また works を使用して、特に構造内にマップがある場合
package main
import "fmt"
import "time"
import "reflect"
type Session struct {
playerId string
beehive string
timestamp time.Time
}
func (s Session) IsEmpty() bool {
return reflect.DeepEqual(s,Session{})
}
func main() {
x := Session{}
if x.IsEmpty() {
fmt.Print("is empty")
}
}
構造体へのポインタを使用すると、変数を逆参照する必要があり、空の構造体へのポインタと比較しないことに注意してください。
session := &Session{}
if (Session{}) == *session {
fmt.Println("session is empty")
}
これを確認してください playground 。
また、ここでは、ポインターのスライスであるプロパティを保持する構造体を同じ方法で比較できないことがわかります...
他の回答の代替として、case
ではなくif
ステートメントを使用して行う場合、最初に意図した方法と同様の構文でこれを行うことができます。
session := Session{}
switch {
case Session{} == session:
fmt.Println("zero")
default:
fmt.Println("not zero")
}