How do I get at the contents of a private reflect.Value in go? - go

I'm trying to make a general purpose debug printer for complex data types because %v has a tendency to just print pointer values rather than what they point at. I've got it working with everything up until I have to deal with structs containing reflect.Value fields.
The following demo code runs without error: (https://play.golang.org/p/qvdRKc40R8k)
package main
import (
"fmt"
"reflect"
)
type MyStruct struct {
i int
R reflect.Value
}
func printContents(value interface{}) {
// Omitted: check if value is actually a struct
rv := reflect.ValueOf(value)
for i := 0; i < rv.NumField(); i++ {
fmt.Printf("%v: ", rv.Type().Field(i).Name)
field := rv.Field(i)
switch field.Kind() {
case reflect.Int:
fmt.Printf("%v", field.Int())
case reflect.Struct:
// Omitted: check if field is actually a reflect.Value to an int
fmt.Printf("reflect.Value(%v)", field.Interface().(reflect.Value).Int())
}
fmt.Printf("\n")
}
}
func main() {
printContents(MyStruct{123, reflect.ValueOf(456)})
}
This prints:
i: 123
R: reflect.Value(456)
However, if I change MyStruct's R field name to r, it fails:
panic: reflect.Value.Interface: cannot return value obtained from unexported field or method
Of course, it's rightly failing because this would otherwise be a way to get an unexported field into proper goland, which is a no-no.
But this leaves me in a quandry: How can I gain access to whatever the unexported reflect.Value refers to without using Interface() so that I can walk its contents and print? I've looked through the reflect documentation and haven't found anything that looks helpful...

After some digging, I've found a solution:
The only way to get at the inner reflect.Value is to call Interface() and type assert it, but this will panic if called on an unexported field. The only way around this is to use the unsafe package to clear the read-only flag so that the Interface() method will think it's exported when it's not (basically, we subvert the type system):
type flag uintptr // reflect/value.go:flag
type flagROTester struct {
A int
a int // reflect/value.go:flagStickyRO
int // reflect/value.go:flagEmbedRO
// Note: flagRO = flagStickyRO | flagEmbedRO
}
var flagOffset uintptr
var maskFlagRO flag
var hasExpectedReflectStruct bool
func initUnsafe() {
if field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag"); ok {
flagOffset = field.Offset
} else {
log.Println("go-describe: exposeInterface() is disabled because the " +
"reflect.Value struct no longer has a flag field. Please open an " +
"issue at https://github.com/kstenerud/go-describe/issues")
hasExpectedReflectStruct = false
return
}
rv := reflect.ValueOf(flagROTester{})
getFlag := func(v reflect.Value, name string) flag {
return flag(reflect.ValueOf(v.FieldByName(name)).FieldByName("flag").Uint())
}
flagRO := (getFlag(rv, "a") | getFlag(rv, "int")) ^ getFlag(rv, "A")
maskFlagRO = ^flagRO
if flagRO == 0 {
log.Println("go-describe: exposeInterface() is disabled because the " +
"reflect flag type no longer has a flagEmbedRO or flagStickyRO bit. " +
"Please open an issue at https://github.com/kstenerud/go-describe/issues")
hasExpectedReflectStruct = false
return
}
hasExpectedReflectStruct = true
}
func canExposeInterface() bool {
return hasExpectedReflectStruct
}
func exposeInterface(v reflect.Value) interface{} {
pFlag := (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + flagOffset))
*pFlag &= maskFlagRO
return v.Interface()
}
There are caveats, in that unsafe isn't allowed or desirable in all environments, not to mention that subverting the type system is rarely the right thing to do. It's recommended that you make such code conditional on build tags, and include a safe alternative.

Related

Golang type switch requires (redundant) type assertion

I would like to use a type switch to call a type specific parsing function
https://play.golang.org/p/2xj_owLL4ZK
package main
import (
"fmt"
)
func main() {
var value interface{}
value = "I am a string"
switch v := value.(type) {
case string:
parseString(value)
default:
fmt.Printf("I don't know about type %T!\n", v)
}
}
func parseString(s string) {
fmt.Println(s)
}
However this does not compile because it's missing a type assertion:
cannot use value (type interface {}) as type string in argument to parseString: need type assertion
Adding a type assertion fixes the error.
https://play.golang.org/p/p0nYNEEJb0Z
package main
import (
"fmt"
)
func main() {
var value interface{}
value = "I am a string"
switch v := value.(type) {
case string:
s, ok := value.(string)
if ok {
parseString(s)
}
default:
fmt.Printf("I don't know about type %T!\n", v)
}
}
func parseString(s string) {
fmt.Println(s)
}
But this feels redundant. I am now checking twice, whether the value is a string.
Should I choose between a type switch and type assertion? Perhaps there is a less redundant way to do this? The example is contrived. There could be many types, which is why a type switch seemed like clean solution...until I started adding type asseertions.
Update
This question has received multiple downvotes. I think this misses the confusing nature of Go's type switch where it appears (initially) as if the value being switched on is the type, not the value.
switch v := value.(type) {
case string:
// ...
case int:
// ...
}
I'm new to Go and incorrectly assumed v was the type. If I ran into this problem when writing Go for this first time, others may too?
Use the value you declared in the switch:
switch v := value.(type) {
case string:
// v is string here
parseString(v)
...

How to access unexported struct fields

Is there a way to use reflect to access unexported fields in Go 1.8?
This no longer seems to work: https://stackoverflow.com/a/17982725/555493
Note that reflect.DeepEqual works just fine (that is, it can access unexported fields) but I can't make heads or tails of that function. Here's a go playarea that shows it in action: https://play.golang.org/p/vyEvay6eVG. The src code is below
import (
"fmt"
"reflect"
)
type Foo struct {
private string
}
func main() {
x := Foo{"hello"}
y := Foo{"goodbye"}
z := Foo{"hello"}
fmt.Println(reflect.DeepEqual(x,y)) //false
fmt.Println(reflect.DeepEqual(x,z)) //true
}
If the struct is addressable, you can use unsafe.Pointer to access the field (read or write) it, like this:
rs := reflect.ValueOf(&MyStruct).Elem()
rf := rs.Field(n)
// rf can't be read or set.
rf = reflect.NewAt(rf.Type(), unsafe.Pointer(rf.UnsafeAddr())).Elem()
// Now rf can be read and set.
See full example on the playground.
This use of unsafe.Pointer is valid according to the documentation and running go vet returns no errors.
If the struct is not addressable this trick won't work, but you can create an addressable copy like this:
rs = reflect.ValueOf(MyStruct)
rs2 := reflect.New(rs.Type()).Elem()
rs2.Set(rs)
rf = rs2.Field(0)
rf = reflect.NewAt(rf.Type(), unsafe.Pointer(rf.UnsafeAddr())).Elem()
// Now rf can be read. Setting will succeed but only affects the temporary copy.
See full example on the playground.
Based on cpcallen's work:
import (
"reflect"
"unsafe"
)
func GetUnexportedField(field reflect.Value) interface{} {
return reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Interface()
}
func SetUnexportedField(field reflect.Value, value interface{}) {
reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).
Elem().
Set(reflect.ValueOf(value))
}
reflect.NewAt might be confusing to read at first. It returns a reflect.Value representing a pointer to a value of the specified field.Type(), using unsafe.Pointer(field.UnsafeAddr()) as that pointer. In this context reflect.NewAt is different than reflect.New, which would return a pointer to a freshly initialized value.
Example:
type Foo struct {
unexportedField string
}
GetUnexportedField(reflect.ValueOf(&Foo{}).Elem().FieldByName("unexportedField"))
https://play.golang.org/p/IgjlQPYdKFR
reflect.DeepEqual() can do it because it has access to unexported features of the reflect package, in this case namely for the valueInterface() function, which takes a safe argument, which denies access to unexported field values via the Value.Interface() method if safe=true. reflect.DeepEqual() will (might) call that passing safe=false.
You can still do it, but you cannot use Value.Interface() for unexported fields. Instead you have to use type-specific methods, such as Value.String() for string, Value.Float() for floats, Value.Int() for ints etc. These will return you a copy of the value (which is enough to inspect it), but will not allow you to modify the field's value (which might be "partly" possible if Value.Interface() would work and the field type would be a pointer type).
If a field happens to be an interface type, you may use Value.Elem() to get to the value contained / wrapped by the interface value.
To demonstrate:
type Foo struct {
s string
i int
j interface{}
}
func main() {
x := Foo{"hello", 2, 3.0}
v := reflect.ValueOf(x)
s := v.FieldByName("s")
fmt.Printf("%T %v\n", s.String(), s.String())
i := v.FieldByName("i")
fmt.Printf("%T %v\n", i.Int(), i.Int())
j := v.FieldByName("j").Elem()
fmt.Printf("%T %v\n", j.Float(), j.Float())
}
Output (try it on the Go Playground):
string hello
int64 2
float64 3
package main
import (
"fmt"
"reflect"
"strings"
"unsafe"
)
type Person1 struct {
W3ID string
Name string
}
type Address1 struct {
city string
country string
}
type User1 struct {
name string
age int
address Address1
manager Person1
developer Person1
tech Person1
}
func showDetails(load, email interface{}) {
if reflect.ValueOf(load).Kind() == reflect.Struct {
typ := reflect.TypeOf(load)
value := reflect.ValueOf(load)
//#1 For struct, not addressable create a copy With Element.
value2 := reflect.New(value.Type()).Elem()
//#2 Value2 is addressable and can be set
value2.Set(value)
for i := 0; i < typ.NumField(); i++ {
if value.Field(i).Kind() == reflect.Struct {
rf := value2.Field(i)
/* #nosec G103 */
rf = reflect.NewAt(rf.Type(), unsafe.Pointer(rf.UnsafeAddr())).Elem()
irf := rf.Interface()
typrf := reflect.TypeOf(irf)
nameP := typrf.String()
if strings.Contains(nameP, "Person") {
//fmt.Println(nameP, "FOUND !!!!!!! ")
for j := 0; j < typrf.NumField(); j++ {
re := rf.Field(j)
nameW := typrf.Field(j).Name
if strings.Contains(nameW, "W3ID") {
valueW := re.Interface()
fetchEmail := valueW.(string)
if fetchEmail == email {
fmt.Println(fetchEmail, " MATCH!!!!")
}
}
}
}
showDetails(irf, email)
} else {
// fmt.Printf("%d.Type:%T || Value:%#v\n",
// (i + 1), value.Field(i), value.Field(i))
}
}
}
}
func main() {
iD := "tsumi#in.org.com"
load := User1{
name: "John Doe",
age: 34,
address: Address1{
city: "New York",
country: "USA",
},
manager: Person1{
W3ID: "jBult#in.org.com",
Name: "Bualt",
},
developer: Person1{
W3ID: "tsumi#in.org.com",
Name: "Sumi",
},
tech: Person1{
W3ID: "lPaul#in.org.com",
Name: "Paul",
},
}
showDetails(load, iD)
}

Default struct values

In Go I get that there are default values for types. Take int in this case which is initialised as a 0.
I have an issue where for me a 0 in an int can be a valid value so I need to check if it's been set by me or initialised as such. Is there any way to tell the difference between them at all?
Considering the following code... I need to be able to tell the difference between testIntOne and testIntTwo but they look the same!
package main
import "log"
type test struct {
testIntOne int
testIntTwo int
}
func main() {
s := test{testIntOne: 0}
log.Println(s)
}
You can't tell the difference, it is not tracked whether a field (or a variable) has been set or not.
Using a pointer
You may use a pointer which has a nil zero value, so if not set, you can tell:
type test struct {
testIntOne *int
testIntTwo *int
}
func main() {
s := test{testIntOne: new(int)}
fmt.Println("testIntOne set:", s.testIntOne != nil)
fmt.Println("testIntTwo set:", s.testIntTwo != nil)
}
Output (try it on the Go Playground):
testIntOne set: true
testIntTwo set: false
Of course new() can only be used to obtain a pointer to an int value being 0. See this question for more options: How do I do a literal *int64 in Go?
Using a method
You may also use a method to set a field, which could take care of additionally tracking the "isSet" property. In this case you must always use the provided method to set the field. Best is to make fields unexported, so others (outside your package) won't have direct access to them.
type test struct {
testIntOne int
testIntTwo int
oneSet, twoSet bool
}
func (t *test) SetOne(i int) {
t.testIntOne, t.oneSet = i, true
}
func (t *test) SetTwo(i int) {
t.testIntTwo, t.twoSet = i, true
}
func main() {
s := test{}
s.SetOne(0)
fmt.Println("testIntOne set:", s.oneSet)
fmt.Println("testIntTwo set:", s.twoSet)
}
Output (try it on the Go Playground):
testIntOne set: true
testIntTwo set: false

Perform an action on a collection of items

In my actual code, I'm parsing an XML document using encoding/xml, and I basically have a bunch of nested structures of the following form — all of which may occur multiple times, except the top-level statements element:
statements
statement
opcode
args
pre
post
I'm fairly new to Go, and I'm clearly misunderstanding how interface{} (the empty interface) works:
.\stmtgen.go:58: cannot use print_name (type func(Statement)) as type func(interface {}) in argument to performAction
.\stmtgen.go:58: cannot use slist (type []Statement) as type []interface {} in argument to performAction
Relevant example code:
package main
import "fmt"
// Actually a structure in my code, but this suffices for demonstration.
type Opcode int
// A Statement has a Name and multiple Opcodes may use this Name.
type Statement struct {
Name string
Opcodes []Opcode
}
// Print the statement name.
func print_name(stmt Statement) {
fmt.Println(stmt.Name)
}
// Perform an action on each item of a collection.
func performAction(action func(interface{}), v []interface{}) {
for i := range v {
action(v[i])
}
}
func main() {
slist := make([]Statement, 3)
slist[0] = Statement{"Statement 1"}
slist[1] = Statement{"Statement 2"}
slist[2] = Statement{"Statement 3"}
//ERROR HERE
performAction(print_name, slist)
}
Must I create functions to print the values for every single type?
An empty interface{} can contain any value and passed around as the type interface{}. when you need the value from it, you can perform a type assertion like this:
var anyValue interface{}
anyValue = "hello"
strValue := anyValue.(string)
If anyValue is not of the type being asserted then it will cause a panic
the type assertion can also be used to return a bool if the interface is of that type with a multiple return
strValue, ok := anyValue.(string)
if ok {
//anyValue contains a string!
}
If you dont know the type of the interface, you can use a switch to determine it's type like this:
switch val := anyValue.(type) {
case string:
// anyValue contains a string
// and val is a string
break
case int:
// anyValue contains an int
// and val is and int
break
default:
//unhandled interface type
}
Hopefully this makes the empty interface{} type clearer.
interfaces{...} which have methods declared in them are different, they can not have members (like structs can), only methods, and their underlying type must implement all the methods declared in the interface. You could have an interface actionPerformer (interface names should have the suffix "er" as they are doing something)
type actionPerformer interface {
action(interface{})
}
A type that implements all the methods in an interface can be cast to that interface type, then if you call one of those methods on the interface, it will run the method on the underlying type.
For example, if the Statement struct implements the action(interface{}) method, the Statement struct can be cast to an actionPerformer type and if the action(interface{}) function is called on the actionPerformer, the action function on the Statement struct is run. So you could have multiple types that all have the action(interface{}) method and they can all be cast to an actionPerformer which you can call the action function on.
func (code Opcode) action(arg interface{}) {
fmt.Println(arg.(int) + int(code))
}
func (stmt Statement) action(arg interface{}) {
fmt.Println(arg.(string), stmt.Name)
}
stmt := Statement{"Statement 1", nil}
stmtActionPerformer := actionPerformer(stmt)
opcode := Opcode(5)
opcodeActionPerformer := actionPerformer(opcode)
stmtActionPerformer.action("hello") // will print "hello "+whatever the statements name is
opcodeActionPerformer.action(2) //will print be 7
Type assertions can still be used on these types of interface e.g.
stmt := stmtActionPerformer.(Statement)
fmt.Println(stmt.Name)
This is a contrived example, but with this in mind, you might want to write your code using interfaces like this.
Remember casting between interfaces is costly, so should be done sparingly, however they are a powerful tool when used correctly.
For your example, a simple printNames function would be much more efficient than all that interface casting (note that in golang, names should be in the CamelCase format, not using underscores)
func printNames(stmts []Statement) {
for _, stmt := range stmts {
fmt.Println(stmt.Name)
}
}
It might also be useful to have a type StatementList and add methods to it:
type StatementList []Statement
func (list StatementList) printNames() {
for _, stmt := range list {
fmt.Println(stmt.Name)
}
}
Getting the hang of this stuff make golang a lot more fun, hope this helps :)
You have to declare the parameters of performAction exactly same like the arguments type.
func performAction(action func(Statement), v []Statement) {
for i := range v {
action(v[i])
}
}
Or you could use interface{} on all parameters instead. Then cast it according to the needs.
func performAction(action interface{}, v interface{}) {
for _, each := range v.([]Statement) {
action.(func(Statement))(each)
}
}
data with type []Statement cannot be assigned to []interface{}
also for type func(Statement) cannot be assigned to func(interface{})
Use interface{}, then cast it to the original type.
this works for me:
package main
import (
"fmt"
)
// Actually a structure in my code, but this suffices for demonstration.
type Opcode int
// A Statement has a Name and multiple Opcodes may use this Name.
type Statement struct {
Name string
Opcodes []Opcode
}
// Print the statement name.
func print_name(stmt interface{}) {
if s, ok := stmt.(Statement); !ok {
panic("typ err")
} else {
fmt.Println(s.Name)
}
}
// Perform an action on each item of a collection.
func performAction(action func(interface{}), v []interface{}) {
for i := range v {
action(v[i])
}
}
func main() {
slist := make([]interface{}, 3)
slist[0] = Statement{"Statement 1", nil}
slist[1] = Statement{"Statement 2", nil}
slist[2] = Statement{"Statement 3", nil}
performAction(print_name, slist)
/*output:
Statement 1
Statement 2
Statement 3
*/
}

How to check variable type at runtime in Go language

I have few C functions declared like this
CURLcode curl_wrapper_easy_setopt_long(CURL* curl, CURLoption option, long param);
CURLcode curl_wrapper_easy_setopt_str(CURL* curl, CURLoption option, char* param);
I would like to expose those as one Go function like this
func (e *Easy)SetOption(option Option, param interface{})
so I need to be able to check param type at runtime. How do I do that and is this good idea (if not what is good practice in this case)?
It seems that Go have special form of switch dedicate to this (it is called type switch):
func (e *Easy)SetOption(option Option, param interface{}) {
switch v := param.(type) {
default:
fmt.Printf("unexpected type %T", v)
case uint64:
e.code = Code(C.curl_wrapper_easy_setopt_long(e.curl, C.CURLoption(option), C.long(v)))
case string:
e.code = Code(C.curl_wrapper_easy_setopt_str(e.curl, C.CURLoption(option), C.CString(v)))
}
}
The answer by #Darius is the most idiomatic (and probably more performant) method. One limitation is that the type you are checking has to be of type interface{}. If you use a concrete type it will fail.
An alternative way to determine the type of something at run-time, including concrete types, is to use the Go reflect package. Chaining TypeOf(x).Kind() together you can get a reflect.Kind value which is a uint type: http://golang.org/pkg/reflect/#Kind
You can then do checks for types outside of a switch block, like so:
import (
"fmt"
"reflect"
)
// ....
x := 42
y := float32(43.3)
z := "hello"
xt := reflect.TypeOf(x).Kind()
yt := reflect.TypeOf(y).Kind()
zt := reflect.TypeOf(z).Kind()
fmt.Printf("%T: %s\n", xt, xt)
fmt.Printf("%T: %s\n", yt, yt)
fmt.Printf("%T: %s\n", zt, zt)
if xt == reflect.Int {
println(">> x is int")
}
if yt == reflect.Float32 {
println(">> y is float32")
}
if zt == reflect.String {
println(">> z is string")
}
Which prints outs:
reflect.Kind: int
reflect.Kind: float32
reflect.Kind: string
>> x is int
>> y is float32
>> z is string
Again, this is probably not the preferred way to do it, but it's good to know alternative options.
quux00's answer only tells about comparing basic types.
If you need to compare types you defined, you shouldn't use reflect.TypeOf(xxx). Instead, use reflect.TypeOf(xxx).Kind().
There are two categories of types:
direct types (the types you defined directly)
basic types (int, float64, struct, ...)
Here is a full example:
type MyFloat float64
type Vertex struct {
X, Y float64
}
type EmptyInterface interface {}
type Abser interface {
Abs() float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func (f MyFloat) Abs() float64 {
return math.Abs(float64(f))
}
var ia, ib Abser
ia = Vertex{1, 2}
ib = MyFloat(1)
fmt.Println(reflect.TypeOf(ia))
fmt.Println(reflect.TypeOf(ia).Kind())
fmt.Println(reflect.TypeOf(ib))
fmt.Println(reflect.TypeOf(ib).Kind())
if reflect.TypeOf(ia) != reflect.TypeOf(ib) {
fmt.Println("Not equal typeOf")
}
if reflect.TypeOf(ia).Kind() != reflect.TypeOf(ib).Kind() {
fmt.Println("Not equal kind")
}
ib = Vertex{3, 4}
if reflect.TypeOf(ia) == reflect.TypeOf(ib) {
fmt.Println("Equal typeOf")
}
if reflect.TypeOf(ia).Kind() == reflect.TypeOf(ib).Kind() {
fmt.Println("Equal kind")
}
The output would be:
main.Vertex
struct
main.MyFloat
float64
Not equal typeOf
Not equal kind
Equal typeOf
Equal kind
As you can see, reflect.TypeOf(xxx) returns the direct types which you might want to use, while reflect.TypeOf(xxx).Kind() returns the basic types.
Here's the conclusion. If you need to compare with basic types, use reflect.TypeOf(xxx).Kind(); and if you need to compare with self-defined types, use reflect.TypeOf(xxx).
if reflect.TypeOf(ia) == reflect.TypeOf(Vertex{}) {
fmt.Println("self-defined")
} else if reflect.TypeOf(ia).Kind() == reflect.Float64 {
fmt.Println("basic types")
}
See type assertions here:
http://golang.org/ref/spec#Type_assertions
I'd assert a sensible type (string, uint64) etc only and keep it as loose as possible, performing a conversion to the native type last.
func (e *Easy)SetOption(option Option, param interface{}) {
if s, ok := param.(string); ok {
// s is string here
}
// else...
}
What's wrong with
func (e *Easy)SetStringOption(option Option, param string)
func (e *Easy)SetLongOption(option Option, param long)
and so on?

Resources