How to get a new variable of the same type of another variable with Golang - go

How can I do this? I want a function to return a variable with the same type as one of its arguments. I need something like the below:
type Whatever struct {
Title string
}
hey:= Whatever{Title:"YAY"}
thetype := reflect.ValueOf(hey).Kind()
// This does not work
BB:= new(thetype)

If you want to create a new value from a reflect.Type you can do it with reflect.New:
thetype := reflect.TypeOf(hey)
BB:= reflect.New(thetype)
This returns a reflect.Value
You can then for example use .Interface() and type assertions to get back to the original type.
Example on Go playground: https://play.golang.org/p/rL-Hm0IUpd

Related

How to get access to a custom type in a reflect.Call return?

I know its not idiomatic to write generic functions in Go, but I want to explore my options before I dive into the go generate.
The problem I have is that the Value.Call() returns a slice where the element I interested in is a pointer to a custom struct. Seems like I cant find a way to access this.
returns := listMethod.Call([]reflect.Value{reflect.ValueOf(filter)})
fmt.Println(returns)
output
[<vspk.EnterpriseProfilesList Value> <*bambou.Error Value>]
type definition:
type EnterpriseProfilesList []*EnterpriseProfile
I want to get access to the vspk.EnterpriseProfilesList, but I am struggling to make it.
If I try to retrieve the underlying value like this:
returns := listMethod.Call([]reflect.Value{reflect.ValueOf(filter)})
ret1 := returns[0].Interface()
fmt.Println(ret1)
I receive
[0xc0000fc7e0]
Value.Call() returns a value of type []reflect.Value. What you're interested in is the first value of that slice: returns[0].
This will be of course of type reflect.Value. To extract the value wrapped in it, use Value.Interface().
This will be of type interface{}. If you need the concrete type, use a type assertion:
returns[0].Interface().(spk.EnterpriseProfilesList)
For example:
if list, ok := returns[0].Interface().(spk.EnterpriseProfilesList); ok {
// here list is of type spk.EnterpriseProfilesList
} else {
// it was nil or not of type spk.EnterpriseProfilesList
}

Assert type based on a string?

Suppose I have the following:
type T struct { Name string }
Then I create a var of type T:
thing := T{"Hello World"}
I then reflect the type:
t := reflect.TypeOf(thing) // main.T
Then I pass t in to a method that accepts an interface, is there any way I can then say, in that method, that the accepted interface{} is of type main.T if I have that string?
The use case is I have a json string that fits a type. I have a string of that type (main.T) and I want to be able to create a new variable that is of type main.t when I only know of the string, main.T then marshal the data to that new variable.
The Go runtime does not provide a way to create a value given the name of a type, but that's something you can implement in the application:
var types = map[string]reflect.Type{
"main.T": reflect.TypeOf((*T)(nil)).Elem(),
}
You can create a new value given the name using:
v := reflect.New(types[name]).Interface()
This assumes that name is a valid name. You may want to check for the case where types[name] == nil.
playground example
You can also do this without reflection:
var types = map[string]func() interface{} {
"main.T": func() interface{} { return &T{} }
}
v := types[name]()

golang: reflect.ValueOf(x).Type() always equals to reflect.TypeOf(x)? [duplicate]

I'm not very clear about what this code snippet behaves.
func show(i interface{}) {
switch t := i.(type) {
case *Person:
t := reflect.TypeOf(i) //what t contains?
v := reflect.ValueOf(i) //what v contains?
tag := t.Elem().Field(0).Tag
name := v.Elem().Field(0).String()
}
}
What is the difference between the type and value in reflection?
reflect.TypeOf() returns a reflect.Type and reflect.ValueOf() returns a reflect.Value. A reflect.Type allows you to query information that is tied to all variables with the same type while reflect.Value allows you to query information and preform operations on data of an arbitrary type.
Also reflect.ValueOf(i).Type() is equivalent to reflect.TypeOf(i).
In the example above, you are using the reflect.Type to get the "tag" of the first field in the Person struct. You start out with the Type for *Person. To get the type information of Person, you used t.Elem(). Then you pulled the tag information about the first field using .Field(0).Tag. The actual value you passed, i, does not matter because the Tag of the first field is part of the type.
You used reflect.Value to get a string representation of the first field of the value i. First you used v.Elem() to get a Value for the struct pointed to by i, then accessed the first Field's data (.Field(0)), and finally turned that data into a string (.String()).

In golang, how to type assert an interface{} to a type specified by a reflect.Type?

For example, I have an interface{} named a, and I also have an reflect.Type called elemType. Now, I want to type assert a to elemType, but a.(elemType) can't be compiled successfully. How to fix it?
Sorry for my confusing expression. My meaning is that I get a type from a function, and I want to type assert an interface{} to this type, but this type is stored in a reflect.Type variable.
What I want to do is similar to the code below:
var a interface{}
//do something
func getType() reflect.Type {
var ret reflect.Type
//do something
return ret
}
targetType := getType()
result := a.(targetType)
Consider a standard type assertion in Go:
v := a.(typeName)
Here the compiler can determine the type of the variable v at compile time, and make use of that knowledge when compiling any further statements involving the variable.
With your example of using a refltect.Type variable in the assertion, it would be impossible to determine the type of v, so the code could not be compiled.
If you need to check that a particular interface variable is of a particular type at runtime, you can still do that with the reflect package. For example:
// if elemType is a normal type
if reflect.ValueOf(a).Type() == elemType {
fmt.Println("type matches")
}
// if elemType is an interface, can check if the value implements it
if reflect.ValueOf(a).Type().Implements(elemType) {
fmt.Println("value implements interface")
}
But you will need a concrete type to return back to standard variables. If you've only got a small selection of possible types, perhaps using a type switch might do what you want.

how to convert interface{} to object in golang?

type Human struct {
Name string
}
func (t *Human) GetInfo() {
fmt.Println(t.Name)
}
func main() {
var p1 interface{}
p1 = Human{Name:"John"}
//p1.GetInfo()
}
now,p1's typs is interface{}, but i want get a Human object.
How to do? i can call p1.GetInfo()
You can use a type assertion to unwrap the value stored in an interface variable. From your example, p1.(Human) would extract a Human value from the variable, or panic if the variable held a different type.
But if your aim is to call methods on whatever is held in the interface variable, you probably don't want to use a plain interface{} variable. Instead, declare the methods you want for the interface type. For instance:
type GetInfoer interface {
GetInfo()
}
func main() {
var p1 GetInfoer
p1 = &Human{Name:"John"}
p1.GetInfo()
}
Go will then make sure you only assign a value with a GetInfo method to p1, and make sure that the method call invokes the method appropriate to the type stored in the variable. There is no longer a need to use a type assertion, and the code will work with any value implementing the interface.
You can do a type assertion inline:
p1.(*Human).GetAll()
http://play.golang.org/p/ldtVrPnZ79
Or you can create a new variable to hold a Human type.

Resources