0
type Test struct { }

I knew this may be the way to check empty struct by (Test{}) == test. However, it seems not working for the struct which only contains one boolean field. Considering this example:

package main

import "fmt"

type Test struct {
  Foo bool
}

func main() {
  empty := Test{}
  test1 := Test{Foo: true}
  test2 := Test{Foo: false}
  fmt.Println(Test{} == test1) //False yay
  fmt.Println(Test{} == test2) //True oh no ...
  fmt.Println(Test{} == empty) //True yay
}

Basically, == thinks the struct containing false field is same to empty struct.

Is there a better way to check the empty struct or am I missing something here ?

Also, you may wonder why only have one field in struct, well, because the struct is in development phase, it may have more fields later on.

Xiaohe Dong
  • 4,953
  • 6
  • 24
  • 53
  • `empty` contains one field, you just didn't explicitly set it to anything. – Hong Ooi Mar 16 '19 at 05:58
  • *"Basically, == thinks the struct containing `false` field is same to empty struct. "* This is because in Go they are the same. If you need to differentiate between **zero values** and **"uninitialized" values** then you'll have to work around this language feature by adding one more bit of information to the value/field. E.g. by making it a pointer or by using a `struct` type like the `sql.NullXxx` types found in `database/sql`. – mkopriva Mar 16 '19 at 06:06
  • Possible duplicate of [How to check for an empty struct?](https://stackoverflow.com/questions/28447297/how-to-check-for-an-empty-struct) – Charlie Tumahai Mar 16 '19 at 15:39

2 Answers2

3

The Go Programming Language Specification

Struct types

A struct is a sequence of named elements, called fields, each of which has a name and a type. Field names may be specified explicitly

// An empty struct.
struct {}

Composite literals

Composite literals construct values for structs, arrays, slices, and maps and create a new value each time they are evaluated. They consist of the type of the literal followed by a brace-bound list of elements. Each element may optionally be preceded by a corresponding key.

A literal may omit the element list; such a literal evaluates to the zero value for its type.

The zero value

When storage is allocated for a variable, either through a declaration or a call of new, or when a new value is created, either through a composite literal or a call of make, and no explicit initialization is provided, the variable or value is given a default value. Each element of such a variable or value is set to the zero value for its type: false for booleans, 0 for numeric types, "" for strings, and nil for pointers, functions, interfaces, slices, channels, and maps. This initialization is done recursively, so for instance each element of an array of structs will have its fields zeroed if no value is specified.


type Test struct {
  Foo bool
}

empty := Test{}

empty is not empty. It is the zero value.

zeroValue := Test{}

or, explicitly,

zeroValue := Test{Foo: false}
peterSO
  • 158,998
  • 31
  • 281
  • 276
0

The struct Test always contains the boolean field Foo. It is just initialized to false if you don't specify its value.

Henry
  • 42,982
  • 7
  • 68
  • 84