Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang type assertion

Tags:

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?

like image 953
Lee Avatar asked Jan 05 '14 14:01

Lee


People also ask

What is Type assertion in go?

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.

How do I convert type in Golang?

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.

What is type switch in Golang?

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.

What is Type Golang?

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.


2 Answers

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

like image 101
Max Avatar answered Oct 26 '22 09:10

Max


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

like image 21
Günter Zöchbauer Avatar answered Oct 26 '22 07:10

Günter Zöchbauer