Here I saw a question about nullable fields in struct. From Go 1.13 you can use sql.NullTime (earlier declared in pg
and mysql
). From now we can use these two options to declare the ResolvedAt
nullable time field:
A. ResolvedAt as NullTime:
type Event struct {
Id int
Resolved bool
CreatedAt time.Time
ResolvedAt sql.NullTime
}
B. ResolvedAt as pointer:
type Event struct {
Id int
Resolved bool
CreatedAt time.Time
ResolvedAt *time.Time
}
For Scan
method there is no difference:
rows, err := db.Query("SELECT * FROM Event")
for rows.Next() {
e:= new(Event)
err := rows.Scan(&e.Id, &e.CreatedAt, &e.ResolvedAt)
}
But when testing for Null there is a difference:
// A.
e.Resolved = (e.ResolvedAt != nil)
// B.
e.Resolved = (e.ResolvedAt.Valid)
In which case is SHOULD to use Null... type rather then pointer?
I would recommend using the sql.Null
types, because it is easier to understand what is going on when reading the code.
If you are using nil pointers it is unclear what you are trying to accomplish by making those fields pointers.
Go lacks null safety, so this is a workaround. Null pointers are problematic. .
By using sql.NullType
you will get the Zero value instead of a Nil
in the scanned field. This fact, when hitting an edge case, could be the difference between panicking or not for your application.
As a rule of thumb, when in doubt, do not use a pointer.