Is there a way to access the name of a "Child" struct from methods on the "Parent" struct when using anonymous method embedding.
For Example:
type Animal struct{}
func (a Animal) SayName() string {
v := reflect.TypeOf(a)
return v.Name()
}
type Zebra struct {
Animal
}
var zebra Zebra
zebraName := zebra.SayName() // "Animal" want "Zebra"
The SayName() method returns the type.Name() of the "Parent".
I realize I could do something like this, but since this for an API and will be reused often. I would prefer to have a solution that is less repetitive.
type Animal struct{
Name string
}
func (a Animal) SayName() string {
return a.Name
}
type Zebra struct {
Animal
}
zebra := &Zebra{Name:"Zebra"}
zebraName := zebra.SayName() // "Zebra"
Any ideas on how this could be accomplished? Is this possible in Go?
Thank you.
An Animal type doesn't know anything about types which may include them as members, so an Animal method can't give you this answer based on the receiver alone. But must this information come from a Zebra method?
func SayName(a interface{}) string {
return reflect.TypeOf(a).Name()
}
works for any type, Zebras included.
I use this way to achieve the late binding:
http://play.golang.org/p/03-rs4bLaV
Which is not so perfect, but a way to achieve this.
Related
We can create structs in golang this way. Examples below:
What are differences between these two?
// Usual way
type Employee struct {
firstName string `json:"name"`
salary int `json:"salary"`
fullTime bool `json:"fullTime"`
projects []Project `json:"projects"`
}
// Un-usal way with pointers
type Employee struct {
firstName *string `json:"name"`
salary *int `json:"salary"`
fullTime *bool `json:"fullTime"`
projects *[]Project `json:"projects"`
}
Are there any trade-offs like memory?
Update:
Assume below function:
// this function consumes MORE memory
func printEmployeeWithoutPointer(employee Employee) {
// print here
}
// this function consumes LESS memory
func printEmployeeWithPointer(employee *Employee) {
// print here
}
Right, there's a number of things to consider. First up: let's start with the obvious syntax error in your pointer example:
type Employee struct {
FirstName *string `json:"name"`
Salary *int `json:"salary"`
FullTime *bool `json:"fullTime"`
}
So I've moved the asterisk to the type, and I've captialized the fields. The encoding/json package uses reflection to set the values of the fields, so they need to be exported.
Seeing as you're using json tags, let's start with the simple things:
type Foo struct {
Bar string `json:"bar"`
Foo *string `json:"foo,omitempty"`
}
When I'm unmarshalling a message that has no bar value, the Bar field will just be an empty string. That makes it kind of hard to work out whether or not the field was sent or not. Especially when dealing with integers: how do I tell the difference between a field that wasn't sent vs a field that was sent with a value of 0?
Using a pointer field, and specify omitempty allows you to do that. If the field wasn't specified in the JSON data, then the field in your struct will be nil, if not: it'll point to an integer of value 0.
Of course, having to check for pointers being nil can be tedious, it makes code more error-prone, and so you only need to do so if there's an actual reason why you'd want to differentiate between a field not being set, and a zero value.
pitfalls
Pointers allow you to change values of what they point to
Let's move on to the risks pointers inherently bring with them. Assuming your Employee struct with pointer fields, and a type called EmployeeV that is the same but with value fields, consider these functions:
func (e Employee) SetName(name string) {
if e.Firstname == nil {
e.Firstname = &name
return
}
*e.Firstname = name
}
Now this function is only going to work half of the time. You're calling SetName on a value receiver. If Firstname is nil, then you're going to set the pointer on a copy of your original variable, and your variable will not reflect the change you made in the function. If Firstname was set, however, the copy will point to the same string as your original variable, and the value that pointer points to will get updated. That's bad.
Implement the same function on EmployeeV, however:
func (e EmployeeV) SetName(name string) {
e.Firstname = name
}
And it simply won't ever work. You'll always update a copy, and the changes won't affect the variable on which you call the SetName function. For that reason, the idiomatic way, in go, to do something like this would be:
type Employee struct {
Firstname string
// other fields
}
func (e *Employee) SetName(name string) {
e.Firstname = name
}
So we're changing the method to use a pointer receiver.
Data races
As always: if you're using pointers, you're essentially allowing code to manipulate the memory something points to directly. Given how golang is a language that is known to facilitate concurrency, and accessing the same bit of memory means you're at risk of creating data-races:
func main() {
n := "name"
e := Employee{
Firstname: &n,
}
go func() {
*e.Firstname = "foo"
}()
race(e)
}
func race(e Employee) {
go race(e)
go func() {
*e.Firstname = "in routine"
}()
*e.Firstname = fmt.Sprintf("%d", time.Now().UnixNano())
}
This Firstname field is accessed in a lot of different routines. What will be its eventual value? Do you even know? The golang race detector will most likely flag this code as a potential data race.
In terms of memory use: individual fields like ints or bools really aren't the thing you ought to be worried about. If you're passing around a sizeable struct, and you know it's safe, then it's probably a good idea to pass around a pointer to said struct. Then again, accessing values through a pointer rather than accessing them directly isn't free: indirection adds a small overhead.
We use pointers to share data, but that doesn't always mean it is more memory efficient or more performant. Go is extremely good and fast at copying data.
When it comes to structs a common reason for using pointers is that pointers can have nil values, where primitives can't. If you need a struct with optionals field, you'd use pointers
If you are deserialising JSON then you could omit fields using omitempty. Here fullTime is optional
type Employee struct {
firstName string `json:"name"`
salary int `json:"salary"`
fullTime *bool `json:"fullTime,omitempty"`
}
Performance when using JSON
If you are deserializing JSON into pointers in the hopes of saving memory, you won't. From a JSON point of view each item is unique, so there is no sharing of data. You will use more memory, because each value now has to store a value and a pointer to the value. And it will be slower because you will need to dereference pointers the whole time
FYI, additional reading https://github.com/golang/go/wiki/CodeReviewComments#pass-values .
Pass Values
Don't pass pointers as function arguments just to save a few bytes. If a function refers to its argument x only as *x throughout, then the argument shouldn't be a pointer. Common instances of this include passing a pointer to a string (*string) or a pointer to an interface value (*io.Reader). In both cases the value itself is a fixed size and can be passed directly. This advice does not apply to large structs, or even small structs that might grow.
Can some one help me understand why it's failing to use the syntax like [Error 1] and [Error 2]?, why [ok 1] is possible and working just fine.
Is the basic design to use Animal as field to serve as generic type good? or any thing bad about it? or any better solution suggested?
package main
import (
pp "github.com/davecgh/go-spew/spew"
)
type Cat struct {
Name string
Age int
}
type Animal interface{}
type House struct {
Name string
Pet *Animal
}
func config() *Animal {
c := Cat{"miao miao", 12}
// return &Animal(c) //fail to take address directly [Error 1]
// return &(Animal(c)) //fail to take address directly [Error 2]
a := Animal(c) //[Ok 1]
return &a
}
func main() {
pp.Dump(config())
pp.Dump(*config())
pp.Dump((*config()).(Cat)) //<-------- we want this
pp.Dump((*config()).(Cat).Name)
pp.Dump("---------------")
cfg := config()
pp.Dump(&cfg)
pp.Dump(*cfg)
pp.Dump((*cfg).(Cat)) //<-------- we want this
pp.Dump((*cfg).(Cat).Name)
pp.Dump("---------------")
}
Ok, two thing:
You cannot take the address of the result of a conversion directly, as it is not "addressable". See the section of the spec about the address-of operator for more information.
Why are you using a pointer to an interface at all? In all my projects I have only ever used an interface pointer once. An interface pointer is basically a pointer to a pointer, sometimes needed, but very rare. Internally interfaces are a type/pointer pair. So unless you need to modify the interface value instead of the value the interface holds then you do not need a pointer. This post may be of interest to you.
Let's assume I have this struct with a method:
package main
import (
"fmt"
"reflect"
)
type MyStruct struct {
}
func (a *MyStruct) AAction() {
fmt.Println("Hello a")
}
Now, if I want to call the method "AAction" by string, I can use reflection (this works):
func main() {
reflect.New(reflect.TypeOf(MyStruct{})).MethodByName("AAction").Call([]reflect.Value{})
}
The problem is, that I don't want to use MyStruct{} as an expression, but as a string. Of course this doesn't work:
func main() {
theStruct := "MyStruct"
theAction := "AAction"
reflect.New(reflect.TypeOf(theStruct)).MethodByName(theAction).Call([]reflect.Value{})
}
because reflect.Typeof(theStruct) would be a string.
I tried reading through the documentation, sadly, I can't find anything very useful.
I found this similar question: Call a Struct and its Method by name in Go?
Under the accepted question, the OP asks:
The issue in my case Is I cant not declare t is typed T, its must be some how I can declare t typed T by the name of T is string "T"
which gets answered by
[...] I would suggest to match the name against the string "T" somewhere in your code [...]
which doesn't solve the problem, as I would still need to call MyStruct{} somewhere.
The question is: is there any way to use a struct by giving the name as a string? (without manually mapping the the name of the struct to the struct)
Working version with using reflect.TypeOf(MyStruct{}):
PlayGround
Not working version, obviously calling the method on a string: PlayGround
Sorry, you can't. The answer is: you could not. There is no builtin or pre-initialized registry of type names.
To get started with reflection (reflect package), you need a value (of the type in question). Based on a string (string name of the type), you can't acquire a value of that type, so you can't get started.
If you do want to do what you want only by a string type name, you need to build your own "registry" prior to doing what you want.
I have managed to do this, but it does not look efficient:
var t reflect.Type
switch t {
case reflect.TypeOf(([]uint8)(nil)):
// handle []uint8 array type
}
First question, are you sure you want to switch on reflect.Type and not use a type switch? Example:
switch x := y.(type) {
case []uint8:
// x is now a []uint8
}
Assuming that will not work for your situation, my recommendation is to make those package variables. Example:
var uint8SliceType = reflect.TypeOf(([]uint8)(nil))
func Foo() {
var t reflect.Type
switch t {
case uint8SliceType:
// handle []uint8 array type
}
}
you may not need reflect if you are just trying to detect type.
switch t := myVar.(type){
case []uint8:
// t is []uint8
case *Foo:
// t is *Foo
default:
panic("unknown type")
}
What are you actually trying to accomplish?
The answer to the initial question How to switch on reflect.Type? is: You can’t. However, you can do it with reflect.Value.
Given a variable v interface{} you can call reflect.TypeOf(v) and reflect.ValueOf(v), which return a reflect.Type or reflect.Value, resp.
If the type of v is not interface{} then these function calls will convert it to interface{}.
reflect.Type contains various run-time information about the type, but it does not contain anything usable to retrieve the type of v itself as needed in a type switch.
Hovewer, reflect.Value provides it through its Interface() method, which returns the underlying value as interface{}. This you can use in a type switch or type assertion.
import "fmt"
import "reflect"
var v int
var rt reflect.Type = reflect.TypeOf(v)
fmt.Println(rt.String(), " has awesome properties: Its alignment is",
rt.Align(), ", it has", rt.Size(), "bytes, is it even comparable?",
rt.Comparable())
// … but reflect.Type won’t tell us what the real type is :(
// Let’s see if reflect.Value can help us.
var rv reflect.Value = reflect.ValueOf(v)
// Here we go:
vi := rv.Interface()
switch vi.(type) {
// Mission accomplished.
}
Perhaps it helps to clarify a few points which may cause confusion about dynamic typing in Go. At least I was confused by this for quite some time.
reflect vs. interface{}
In Go there are two systems of run-time generics:
In the language: interface{}, useful for type switches/assertions,
In the library: The reflect package, useful for inspection of run-time generic types and values of such.
These two systems are separated worlds, and things that are possible with one are impossible with the other. For example, Given an interface{}, it is in plain Go (with safe code) impossible to, say, if the value is an array or slice, regardless of its element type, then get the value of the i-th element. One needs to use reflect in order to do that. Conversely, with reflect it is impossible to make a type switch or assertion: convert it to interface{}, then you can do that.
There are only very few points of an interface between these systems. In one direction it is the TypeOf() and ValueOf() functions which accept interface{} and return a reflect struct. In the other direction it is Value.Interface().
It is a bit counter-intuitive that one needs a Value, not a Type, to do a type switch. At least this is somewhat consistent with the fact that one needs a value construct a Type by calling TypeOf().
reflect.Kind
Both reflect.Type and reflect.Value have a Kind() method. Some suggest using the value these methods return, of type reflect.Kind, to imitate a type switch.
While this may be useful in certain situations, it is not a replacement for a type switch. For example, using Kind one cannot distinguish between int64 and time.Duration because the latter is defined as
type Duration int64
Kind is useful to tell if a type is any kind of struct, array, slice etc., regardless of the types it is composed of. This is not possible to find out with a type switch.
(Side note. I had the same question and found no answer here helpful so I went to figure it out myself. The repeated counter-question “why are you doing this?”, followed by unrelated answers did not help me either. I have a good reason why I want to do it precisely this way.)
This might work.
switch t := reflect.TypeOf(a).String() {
case "[]uint8":
default:
}
As others have said, it's not clear what you are trying to achieve by switching on reflect.Type However, I came across this question when probably trying to do something similar, so I will give you my solution in case it answers your question.
As captncraig said, a simple type switch could be done on a interface{} variable without needing to use reflect.
func TypeSwitch(val interface{}) {
switch val.(type) {
case int:
fmt.Println("int with value", val)
case string:
fmt.Println("string with value ", val)
case []uint8:
fmt.Println("Slice of uint8 with value", val)
default:
fmt.Println("Unhandled", "with value", val)
}
}
However, going beyond this, the usefulness of reflection in the context of the original question could be in a function that accepts a struct with arbitrarily typed fields, and then uses a type switch to process the field according to its type. It is not necessary to switch directly on reflect.Type, as the type can be extracted by reflect and then a standard type switch will work. For example:
type test struct {
I int
S string
Us []uint8
}
func (t *test) SetIndexedField(index int, value interface{}) {
e := reflect.ValueOf(t).Elem()
p := e.Field(index)
v := p.Interface()
typeOfF := e.Field(index).Type()
switch v.(type) {
case int:
p.SetInt(int64(value.(int)))
case string:
p.SetString(value.(string))
case []uint8:
p.SetBytes(value.([]uint8))
default:
fmt.Println("Unsupported", typeOfF, v, value)
}
}
The following examples demonstrate the use of this function:
var t = test{10, "test string", []uint8 {1, 2, 3, 4}}
fmt.Println(t)
(&t).SetIndexedField(0, 5)
(&t).SetIndexedField(1, "new string")
(&t).SetIndexedField(2, []uint8 {8, 9})
fmt.Println(t)
(A few points on reflection in go:
It is necessary to export the struct fields for reflect to be able to use them, hence the capitalisation of the field names
In order to modify the field values, it would be necessary to use a pointer to the struct as in this example function
Elem() is used to "dereference" the pointer in reflect
)
Well, I did this by first transfer it to interface and then use the.(type)
ty := reflect.TypeOf(*c)
vl := reflect.ValueOf(*c)
for i:=0;i<ty.NumField();i++{
switch vl.Field(i).Interface().(type) {
case string:
fmt.Printf("Type: %s Value: %s \n",ty.Field(i).Name,vl.Field(i).String())
case int:
fmt.Printf("Type: %s Value: %d \n",ty.Field(i).Name,vl.Field(i).Int())
}
}
Let's say I have a lot of different struct types which all satisfy an interface, Food.
type Food interface {
Name() string
Tastiness() int
}
type fruit struct {
species string
numSeeds int
}
type vegetable struct {
commonName string
weight int
}
func (f *fruit) Name() string { return f.species }
func (f *fruit) Tastiness() int { return 100 - f.numSeeds }
func (v *vegetable) Name() string { return v.commonName }
func (v *vegetable) Tastiness() int { return 1 }
The structs that satisfy the Food interface do so with functions that are pointer receivers because I pass them around often, which is unwieldy without pointers.
Often, I want to make comparisons between food1 and food2, and so I construct maps that look like foodmap := map[Food]bool. What I really want to check is if the underlying structs are the same thing. But, because it's always pointers that are satisfying the interface, I can't do equality or presence tests using maps or lists if I create two of the same kind of fruit or vegetable, for example.
Is the best way to compare Foods to not use map[Food]bool and instead use something like map[FoodKey], where any struct that satsifies Food provides a FoodKey() comparisonStruct method that returns a struct meant strictly for comparison?
Is the best way to compare Foods to not use map[Food]bool and instead use something like map[FoodKey], where any struct that satsifies Food provides a FoodKey() comparisonStruct method that returns a struct meant strictly for comparison?
I suspect it is a better approach, considering:
comparing interface is slow (issue 6105)
(and that supposes comparison operators are defined: see Map Types)
using an Equaler (as in this thread) isn't easy
you might need to distinguish between the actual types included in the interface instances you are comparing.
I believe the most efficient path here is to add an extra function to your interface like Is(f Food) bool, it's easy to implement, no overhead of using reflection or comparing interfaces or using a map somewhere.
Example:
type Food interface {
Name() string
Tastiness() int
Is(f Food) bool
}
//....
func (*fruit) Is(f Food) bool { _, ok := f.(*fruit); return ok }
//....
func (*vegetable) Is(f Food) bool { _, ok := f.(*vegetable); return ok }
playground
You have two options to determine or compare the underlying structs of interfaces.
1- Use the reflect package, specifically the reflect.TypeOf function, which will return the dynamic type of the interface, such as:
x := Food(fruit{"banana", 0})
y := Food(vegetable{"potato, 45})
return reflect.TypeOf(x) == reflect.TypeOf(y)
This piece of code will return false.
2- Use type assertions or a type switch, such as:
value, ok := yourInterface.(possibleType)