I have created a type Role based off string, and I am now trying to get it to work with the database driver by implementing the Valuer and Scanner interfaces
type Role string func (r *Role) Scan(value interface{}) error { r = (*Role)(value.(string)) return nil } func (r *Role) Value(value driver.Value, err error) { if err != nil { value = string(r) } }
I keep getting the error:
The Go code app/entities/user.go does not compile: cannot convert value.(string) (type string) to type *Role
What am I doing wrong here?
Type assertions in Golang provide access to the exact type of variable of an interface. If already the data type is present in the interface, then it will retrieve the actual data type value held by the interface. A type assertion takes an interface value and extracts from it a value of the specified explicit type.
Type conversion happens when we assign the value of one data type to another. Statically typed languages like C/C++, Java, provide the support for Implicit Type Conversion but Golang is different, as it doesn't support the Automatic Type Conversion or Implicit Type Conversion even if the data types are compatible.
A switch is a multi-way branch statement used in place of multiple if-else statements but can also be used to find out the dynamic type of an interface variable.
Type is the base interface for all data types in Go. This means that all other data types (such as int , float , or string ) implement the Type interface. Type is defined in the reflect header.
Here is working code for the first function:
func (r *Role) Scan(value interface{}) error { *r = Role(value.(string)) return nil }
Although you may wish to use s, ok := value.(string)
and return an error for !ok
instead of panic-ing.
The signature for the a driver.Valuer
is not what you gave but:
func (r Role) Value() (driver.Value, error) { return string(r), nil }
Note this doesn't handle or produce NULL values.
Playground
I don't think it's a good idea to modify the receiver of your method (r) in the Scan method.
You need a type assertion to convert value interface{}
to string.
You are trying to convert a string
to a pointer to Role
.
func (r *Role) Scan(value interface{}) (retVal Role, err error) { var s string; if v,ok := value.(string); ok { s = v; } var rx Role rx = Role(s) var rx2 *Role rx2 = &rx _ = rx // just to silence the compiler for this demonstration _ = rx2 // just to silence the compiler for this demonstration return rx, nil }
should work
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With