Golang change type of pointer interface - go

I have a function which returns a slice of pointers of some interface. I want to change the type later in the code to the implementation type but nothing works, I still get an invalid type assertion.
Example
func Test(c Parsable)([]*Parsable, error) {
// generate slice by factory method on Parsable inteface and return slice
}
var implParsable ImplParsable
results, err := Test(implParsable)
data := results[0].(ImplParsable) // I tried this in many variations but nothing works

resultSets[0] is a pointer to an interface, so you need to dereference that pointer to get the interface value, which you can do inline since slice values are addressable.
data := (*resultSets[0]).(ImplParsable)

Related

get reflect.struct from interface

hi a have this func for get type of value, but i try this and never can get reflect.struct:
type Test struct {
Code int
Name string
}
func main(){
test := getTest()
data, err := getBytes(slice...)
sanitizedFile := bytes.Split(data, []byte("\r\n"))
err = Unmarshal(sanitizedFile[0], &test)
}
func getTest() interface{} {
return Test{}
}
With this code i don't can get the reflecet.struct from v params in Unmarshall func
func Unmarshal(data []byte, v interface{}) error {
rv := reflect.ValueOf(v)
if rv.Kind() == reflect.Ptr {
rvElem := rv.Elem()
switch rvElem.Kind() {
case reflect.Struct:
// implement me
}
}
return ErrInvalid
}
I would like to know if I can somehow find out if an interface is of type struct or access the values ​​of that struct.
I think the real problem here is illustrated by this quote:
I would like to know if I can somehow find out if an interface is of type struct or access the values ​​of that struct.
An interface value isn't "of type struct". Never! An interface value can contain a value whose type is some structure, but it is not a value of that type. It just contains one. This is similar to the way that a box1 you get from Amazon can contain a corkscrew, but the box is not a corkscrew, ever.
Given a non-nil value of type interface I for some interface type I, you know that you have a value that implements the methods of I. Since {} is the empty set of methods, all types implement it, so given a (still non-nil) value of type interface{}, you have a value that implements no methods. That's not at all useful by itself: it means you can invoke no methods, which means you can't do anything method-like.
But just because you can't do anything method-y doesn't mean you can't do anything at all. Any interface value, regardless of the interface type, can have a type-assertion used on it:
iv := somethingThatReturnsAnInterface()
cv := iv.(struct S) // assert that iv contains a `struct S`
If iv does in fact contain a struct S value—if that's what's inside the box once you open it—then this type-assertion doesn't panic, and cv winds up with the concrete value of type struct S. If panic is undesirable, we can use the cv, ok := iv.(struct S) form, or a type switch. All of these—including the version that panics—work by checking the type of the value inside the interface.
What this—or, more precisely, the way the Go language is defined—tells us is that the interface "box" really holds two things:
a concrete type, and
a concrete value.
Well, that is, unless it holds a <nil, nil> pair, in which case iv == nil is true. Note that the iv == nil test actually tests both parts.
If Go had a syntax for this, we could write something like iv.type and iv.value to get at the two separate parts. But we can't do that. We have to use type assertions, type-switch, or reflect. So, going back to this:
I would like to know if I can somehow find out if an interface is of type struct
we can see that the question itself is just a little malformed. We don't want to know if an interface value has this type. We want to know if a non-nil interface's held value is of this type, as if we could inspect iv.type and iv.value directly.
If you have a limited set of possible types, you can use the type-switch construct, and enumerate all your allowed possiblities:
switch cv := iv.(type) {
case struct S:
// work with cv, which is a struct S
case *struct S:
// work with cv, which is a *struct S
// add more cases as appropriate
}
If you need more generality, instead of doing the above, we end up using the reflect package:
tv := reflect.TypeOf(iv)
or:
vv := reflect.ValueOf(iv)
The latter is actually the more useful form, since vv captures both the iv.type pseudo-field and the iv.value pseudo-field.
As mkopriva notes in a comment, test, in your sample code, has type interface{}, so &test has type *interface{}. In most cases this is not a good idea: you just want to pass the interface{} value directly.
To allow the called function to set the object to a new value, you will want to pass a pointer to the object as the interface value. You do not want to pass a pointer to the interface while having the interface hold the struct "in the box" as it were. You need a reflect.Value on which you can invoke Set(), and to get one, you will need to follow an elem on the reflect.Value that is a pointer to the struct (not one that is a pointer to the interface).
There's a more complete example here on the Go Playground.
1This is partly an allusion to "boxed values" in certain other programming languages (see What is boxing and unboxing and what are the trade offs?), but partly literal. Don't mistake Go's interfaces for Java's boxed values, though: they are not the same at all.
Maybe what you need is type assertion?
t, ok := v.(myStruct)
https://tour.golang.org/methods/15
In any case this code prints "struct":
type tt struct {}
var x tt
var z interface{}
z = x
v := reflect.ValueOf(z).Kind()
fmt.Printf("%v\n", v)
And see this for setting the value of a struct field using reflection:
Using reflect, how do you set the value of a struct field?

What is the difference between reflect.ValueOf() and Value.Elem() in go?

I started learning golang a couple of days ago and found reflect.Valueof() and Value.Elem() quite confusing. What is the difference between this two function/methods and how to use them correctly?
Both function/methods return a Value, and according to the go doc
ValueOf returns a new Value initialized to the concrete value stored in the interface i. ValueOf(nil) returns the zero Value.
Elem returns the value that the interface v contains or that the pointer v points to. It panics if v's Kind is not Interface or Ptr. It returns the zero Value if v is nil.
I found this code from a post on stackoverflow but still don't understand when to use .Elem()
func SetField(obj interface{}, name string, value interface{}) error {
// won't work if I remove .Elem()
structValue := reflect.ValueOf(obj).Elem()
structFieldValue := structValue.FieldByName(name)
if !structFieldValue.IsValid() {
return fmt.Errorf("No such field: %s in obj", name)
}
if !structFieldValue.CanSet() {
return fmt.Errorf("Cannot set %s field value", name)
}
structFieldType := structFieldValue.Type()
// won't work either if I add .Elem() to the end
val := reflect.ValueOf(value)
if structFieldType != val.Type() {
return fmt.Errorf("Provided value %v type %v didn't match obj field type %v",val,val.Type(),structFieldType)
}
structFieldValue.Set(val)
return nil
}
reflect.ValueOf() is a function, think of it as the entry point to reflection. When you have a "non-reflection" value, such as a string or int, you can use reflect.ValueOf() to get a reflect.Value descriptor of it.
Value.Elem() is a method of reflect.Value. So you can only use this if you already have a reflect.Value. You may use Value.Elem() to get the value (reflect.Value) pointed by the value wrapped by the original reflect.Value. Note that you may also use reflect.Indirect() for this. There's another "use case" for Value.Elem(), but it's more "advanced", we return to it at the end of the answer.
To "leave" reflection, you may use the general Value.Interface() method, which returns you the wrapped value as an interface{}.
For example:
var i int = 3
var p *int = &i
fmt.Println(p, i)
v := reflect.ValueOf(p)
fmt.Println(v.Interface()) // This is the p pointer
v2 := v.Elem()
fmt.Println(v2.Interface()) // This is i's value: 3
This will output (try it on the Go Playground):
0x414020 3
0x414020
3
For a great introduction to Go's reflection, read The Go Blog: The Laws of Reflection. Although if you're just starting with Go, I'd focus on other things and leave reflection for a later adventure.
Another use case for Value.Elem()
This is kind of an advanced topic, so don't freak out if you don't understand it. You don't need to.
We saw how Value.Elem() can be used to "navigate" when a pointer is wrapped in the reflect.Value. Doc of Value.Elem() says:
Elem returns the value that the interface v contains or that the pointer v points to.
So if reflect.Value wraps an interface value, Value.Elem() may also be used to get the concrete value wrapped in that interface value.
Interfaces in Go is its own topic, for the internals, you may read Go Data Structures: Interfaces by Russ Cox. Again, not necessarily a topic for Go starters.
Basically whatever value you pass to reflect.ValueOf(), if it's not already an interface value, it will be wrapped in an interface{} implicitly. If the passed value is already an interface value, then the concrete value stored in it will be passed as a interface{}. This second "use case" surfaces if you pass a pointer to interface (which is otherwise very rare in Go!).
So if you pass a pointer to interface, this pointer will be wrapped in an interface{} value. You may use Value.Elem() to get the pointed value, which will be an interface value (not a concrete value), and using Value.Elem() again on this will give you the concrete value.
This example illustrates it:
var r io.Reader = os.Stdin // os.Stdin is of type *os.File which implements io.Reader
v := reflect.ValueOf(r) // r is interface wrapping *os.File value
fmt.Println(v.Type()) // *os.File
v2 := reflect.ValueOf(&r) // pointer passed, will be wrapped in interface{}
fmt.Println(v2.Type()) // *io.Reader
fmt.Println(v2.Elem().Type()) // navigate to pointed: io.Reader (interface type)
fmt.Println(v2.Elem().Elem().Type()) // 2nd Elem(): get concrete value in interface: *os.File
Try it on the Go Playground.

why unmarshal make the type of object changed in golang

I want to write a mockData method which can accept several types of parameter and return correspond objects based on its json data. The code as below:
func MockData(jsonPath string,v interface{})(interface{},error){
var ret interface{}
data,_ := ioutil.ReadFile(jsonPath)
switch v.(type) {
case Req:
ret = Req{}
fmt.Printf("\n===before Unmarshal==%T===\n",ret)
err = json.Unmarshal(data,&ret)
if err!=nil{...}
fmt.Printf("======after unmarshal===%T\n",ret)
case ...
default:
fmt.Printf("error===not match")
}
return ret,err
}
However, it panics when I use it. The code as below:
func main(){
reqJsonPath := /xx/yy/req.json
obj,err:=test.MockData(jsonFile,Req{})
if err!=nil{...}
require := obj.(Req) //panic cant []interface{} to Req
}
and the output of MockData is:
===before Unmarshal==Req===
======after unmarshal===[]interface{}
the type of object changed after unmarshal. and some more strange is that if I replace:
ret = Req{}
with
ret = &Req{}
the output will be same as below:
===before Unmarshal==*Req===
======after unmarshal===*Req
To reproduce the problem more conveniently I give the Require struct as below:
type Req []*Ele
type Ele struct {
ID int
Level int
}
summary:
Can I achieve expected function which produces different types of objects based on its json and type?
Why does the type of object changed after unmarshal, and why it not changed after I add &?
Can I achieve expected function which produces different types of objects based on its json and type?
func MockData(filename string, v interface{}) (interface{}, error) {
data, _ := ioutil.ReadFile(filename)
switch t := v.(type) {
case Req:
// t at this point is a Req{}
err := json.Unmarshal(data, &t)
return t, err
}
return nil, errors.New("unknown type")
}
I don't really know your motivation why you you need to pass an actual struct rather than a pointer. Check this demonstration
Why does the type of object changed after unmarshal, and why it not changed after I add &?
When you unmarshal using &ret where ret is an interface, you are getting the address of the interface. Hence, json.Unmarshal() will see that the backing data is a interface rather than a pointer to a struct. The default data type that json.Unmarshal() will use is map[string]interface{} for objects and []interface{} for arrays.
Now if you unmarshal using ret where ret is &Req{}, json.Unmarshal() will check that the backing data is a struct, hence it can do it's unmarshaling using the struct's fields.
Edit:
You seem to be confused by pointer to an interface which is different to an interface which has a pointer. Try this code and you'll see the difference.
var x interface{} = Req{}
var y interface{} = &x
var z interface{} = &Req{}
fmt.Printf("%T\n", y)
fmt.Printf("%T\n", z)
Remember that interfaces are just normal values and they also take memory. Now if you take an address of that memory, you get the pointer to the interface rather than the pointer to the data the interface is referring to.
Can I achieve expected function which produces different types of objects based on its json and type?
Yes, but you'll have to convert it back using a type assertion at the calling end ie
MyFoo:=MockData("foo.json", Foo{}).(Foo)
(or have multiple return ret.(Foo) return ret.(Bar) in the func)
Why does the type of object changed after unmarshal, and why it not changed after I add &?
There are some helpful comments in the top of the Unmarshal source
namely
// To unmarshal JSON into a pointer, Unmarshal first handles the case of
// the JSON being the JSON literal null. In that case, Unmarshal sets
// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into
// the value pointed at by the pointer. If the pointer is nil, Unmarshal
// allocates a new value for it to point to.
and
// To unmarshal JSON into an interface value,
// Unmarshal stores one of these in the interface value:
//
// bool, for JSON booleans
// float64, for JSON numbers
// string, for JSON strings
// []interface{}, for JSON arrays
// map[string]interface{}, for JSON objects
// nil for JSON null
So in the first case you are unmarshalling into an interface value (ret is declared as an interface{})
In the second case there is a pointer to a struct so that's what you get

Using empty interfaces in go

I am trying to understand the code that is used at my company. I am new to go lang, and I have already gone through the tutorial on their official website. However, I am having a hard time wrapping my head around empty interfaces, i.e. interface{}. From various sources online, I figured out that the empty interface can hold any type. But, I am having a hard time figuring out the codebase, especially some of the functions. I will not be posting the entire thing here, but just the minimal functions in which it has been used. Please bear with me!
Function (I am trying to understand):
func (this *RequestHandler) CreateAppHandler(rw http.ResponseWriter, r *http.Request) *foo.ResponseError {
var data *views.Data = &views.Data{Attributes: &domain.Application{}}
var request *views.Request = &views.Request{Data: data}
if err := json.NewDecoder(r.Body).Decode(request); err != nil {
logrus.Error(err)
return foo.NewResponsePropogateError(foo.STATUS_400, err)
}
requestApp := request.Data.Attributes.(*domain.Application)
requestApp.CreatedBy = user
Setting some context, RequestHandler is a struct defined in the same package as this code. domain and views are seperate packages. Application is a struct in the package domain. The following two structs are part of the package views:
type Data struct {
Id string `json:"id"`
Type string `json:"type"`
Attributes interface{} `json:"attributes"`
}
type Request struct {
Data *Data `json:"data"`
}
The following are part of the package json:
func NewDecoder(r io.Reader) *Decoder {
return &Decoder{r: r}
}
func (dec *Decoder) Decode(v interface{}) error {
if dec.err != nil {
return dec.err
}
if err := dec.tokenPrepareForDecode(); err != nil {
return err
}
if !dec.tokenValueAllowed() {
return &SyntaxError{msg: "not at beginning of value"}
}
// Read whole value into buffer.
n, err := dec.readValue()
if err != nil {
return err
}
dec.d.init(dec.buf[dec.scanp : dec.scanp+n])
dec.scanp += n
// Don't save err from unmarshal into dec.err:
// the connection is still usable since we read a complete JSON
// object from it before the error happened.
err = dec.d.unmarshal(v)
// fixup token streaming state
dec.tokenValueEnd()
return err
}
type Decoder struct {
r io.Reader
buf []byte
d decodeState
scanp int // start of unread data in buf
scan scanner
err error
tokenState int
tokenStack []int
}
Now, I understood that, in the struct Data in package views, Application is being set as a type for the empty interface. After that, a pointer to Request in the same package is created which points to the variable data.
I have the following doubts:
What exactly does this keyword mean in Go? What is the purpose of writing this * RequestHandler?
Initialization of a structure in Go can be done while assigning it to a variable by specifying the values of all it's members. However, here, for the struct Data, only the empty interface value is assigned and the values for the other two fields are not assigned?
What is the advantage of assigning the Application struct to an empty interface? Does it mean I can use the struct members using the interface variable directly?
Can someone help me figure out the meaning of this statement? json.NewDecoder(r.Body).Decode(request)?
While I know this is too much, but I am having a hard time figuring out the meaning of interfaces in Go. Please help!
this is not a keyword in go; any variable name can be used there. That is called the receiver. A function declared in that way must be called like thing.func(params), where "thing" is an expression of the type of the receiver. Within the function, the receiver is set to the value of thing.
A struct literal does not have to contain values for all the fields (or any of them). Any fields not explicitly set will have the zero value for their types.
As you said, an empty interface can take on a value of any type. To use a value of type interface{}, you would use type assertion or a type switch to determine the type of the value, or you could use reflection to use the value without having to have code for the specific type.
What specifically about that statement do you not understand? json is the name of a package in which the function NewDecoder is declared. That function is called, and then the Decode function (which is implemented by the type of the return value of NewDecoder) is called on that return value.
You may want to take a look at Effective Go and/or The Go Programming Language Specification for more information.

Cast boxed struct to boxed pointer - golang

I'm using Protobuf for Golang.
Protobuf generates message types where type pointer implements proto.Message().
e.g.
func (*SomeMessage) Message() {}
The protobuf lib have methods like Marshal(proto.Message)
Now to my actual issue.
message := SomeMessage {}
SendMessage(&message)
func SendMessage(message interface{}) {
switch msg := message.(type) {
case proto.Message:
//send across the wire or whatever
default:
//non proto message, panic or whatever
}
}
The above works fine.
However, If I don't pass the message as a pointer, then the code in SendMessage will not match, as the interface is only implemented on the SomeMessage pointer, not on the value.
What I would like to do is:
message := SomeMessage {}
SendMessage(message) //pass by value
//there are more stuff going on in my real code, but just trying to show the relevant parts
func SendMessage(message interface{}) {
//match both pointer and value as proto.Message
//and then turn the value into a pointer so that
//other funcs or protobuf can consume it
message = MagicallyTurnBoxedValueIntoBoxedStruct(message)
switch msg := message.(type) {
case proto.Message:
//send across the wire or whatever
default:
//non proto message, panic or whatever
}
}
preferably I'd like to be able to pass both as pointer and as value.
The reason why I want to pass by value, is that this can act as a poor mans isolation when passing messages across goroutines/threads etc.
(in lack of immutability)
All of this could probably be avoided if the protobuf generator generated allowed values to be treated as proto.Message() too.
Or if there was some nicer way to do immutable messages.
It's not super important,if its possible, cool, if its not, meh :-)
[EDIT]
If I have the reflect.Type of the message and the reflect.Type of the pointer type of the message.
Is it somehow possible to create an instance of the pointer type pointing to the value using "reflect" ?
Normally, you can't take the address of a value which means you can't simply convert the interface{} to a pointer to satisfy Protobuf's requirement.
That said, you can dynamically create a new pointer then copy the value in to that then pass the newly allocated pointer to protobuf.
Here's an example on Play
The value -> pointer conversion is:
func mkPointer(i interface{}) interface{} {
val := reflect.ValueOf(i)
if val.Kind() == reflect.Ptr {
return i
}
if val.CanAddr() {
return val.Addr().Interface()
}
nv := reflect.New(reflect.TypeOf(i))
nv.Elem().Set(val)
return nv.Interface()
}
We first see if it's a pointer, if so, just return the value.
Then we check to see if it's addressable and return that.
Lastly, we make a new instance of the type and copy the contents to that and return it.
Since this this copies the data, it may not be practical for your purposes. It will all depend on size of message and expected rate of calling with a value (as that will generate more garbage).

Resources