How to find the type of an object in Go? - go

How do I find the type of an object in Go? In Python, I just use typeof to fetch the type of object. Similarly in Go, is there a way to implement the same ?
Here is the container from which I am iterating:
for e := dlist.Front(); e != nil; e = e.Next() {
lines := e.Value
fmt.Printf(reflect.TypeOf(lines))
}
I am not able to get the type of the object lines in this case which is an array of strings.

The Go reflection package has methods for inspecting the type of variables.
The following snippet will print out the reflection type of a string, integer and float.
package main
import (
"fmt"
"reflect"
)
func main() {
tst := "string"
tst2 := 10
tst3 := 1.2
fmt.Println(reflect.TypeOf(tst))
fmt.Println(reflect.TypeOf(tst2))
fmt.Println(reflect.TypeOf(tst3))
}
Output:
string
int
float64
see: http://play.golang.org/p/XQMcUVsOja to view it in action.
More documentation here: http://golang.org/pkg/reflect/#Type

I found 3 ways to return a variable's type at runtime:
Using string formatting
func typeof(v interface{}) string {
return fmt.Sprintf("%T", v)
}
Using reflect package
func typeof(v interface{}) string {
return reflect.TypeOf(v).String()
}
Using type switch
func typeof(v interface{}) string {
switch v.(type) {
case int:
return "int"
case float64:
return "float64"
//... etc
default:
return "unknown"
}
}
Every method has a different best use case:
string formatting - short and low footprint (not necessary to import reflect package)
reflect package - when need more details about the type we have access to the full reflection capabilities
type switch - allows grouping types, for example recognize all int32, int64, uint32, uint64 types as "int"

Use the reflect package:
Package reflect implements run-time reflection, allowing a program to
manipulate objects with arbitrary types. The typical use is to take a
value with static type interface{} and extract its dynamic type
information by calling TypeOf, which returns a Type.
package main
import (
"fmt"
"reflect"
)
func main() {
b := true
s := ""
n := 1
f := 1.0
a := []string{"foo", "bar", "baz"}
fmt.Println(reflect.TypeOf(b))
fmt.Println(reflect.TypeOf(s))
fmt.Println(reflect.TypeOf(n))
fmt.Println(reflect.TypeOf(f))
fmt.Println(reflect.TypeOf(a))
}
Produces:
bool
string
int
float64
[]string
Playground
Example using ValueOf(i interface{}).Kind():
package main
import (
"fmt"
"reflect"
)
func main() {
b := true
s := ""
n := 1
f := 1.0
a := []string{"foo", "bar", "baz"}
fmt.Println(reflect.ValueOf(b).Kind())
fmt.Println(reflect.ValueOf(s).Kind())
fmt.Println(reflect.ValueOf(n).Kind())
fmt.Println(reflect.ValueOf(f).Kind())
fmt.Println(reflect.ValueOf(a).Index(0).Kind()) // For slices and strings
}
Produces:
bool
string
int
float64
string
Playground

To get a string representation:
From http://golang.org/pkg/fmt/
%T a Go-syntax representation of the type of the value
package main
import "fmt"
func main(){
types := []interface{} {"a",6,6.0,true}
for _,v := range types{
fmt.Printf("%T\n",v)
}
}
Outputs:
string
int
float64
bool

I would stay away from the reflect. package. Instead use %T
package main
import (
"fmt"
)
func main() {
b := true
s := ""
n := 1
f := 1.0
a := []string{"foo", "bar", "baz"}
fmt.Printf("%T\n", b)
fmt.Printf("%T\n", s)
fmt.Printf("%T\n", n)
fmt.Printf("%T\n", f)
fmt.Printf("%T\n", a)
}

Best way is using reflection concept in Google.
reflect.TypeOf gives type along with the package name
reflect.TypeOf().Kind() gives underlining type

To be short, please use fmt.Printf("%T", var1) or its other variants in the fmt package.

If we have this variables:
var counter int = 5
var message string = "Hello"
var factor float32 = 4.2
var enabled bool = false
1: fmt.Printf %T format : to use this feature you should import "fmt"
fmt.Printf("%T \n",factor ) // factor type: float32
2: reflect.TypeOf function : to use this feature you should import "reflect"
fmt.Println(reflect.TypeOf(enabled)) // enabled type: bool
3: reflect.ValueOf(X).Kind() : to use this feature you should import "reflect"
fmt.Println(reflect.ValueOf(counter).Kind()) // counter type: int

You can check the type of any variable/instance at runtime either using the "reflect" packages TypeOf function or by using fmt.Printf():
package main
import (
"fmt"
"reflect"
)
func main() {
value1 := "Have a Good Day"
value2 := 50
value3 := 50.78
fmt.Println(reflect.TypeOf(value1 ))
fmt.Println(reflect.TypeOf(value2))
fmt.Println(reflect.TypeOf(value3))
fmt.Printf("%T",value1)
fmt.Printf("%T",value2)
fmt.Printf("%T",value3)
}

To get the type of fields in struct
package main
import (
"fmt"
"reflect"
)
type testObject struct {
Name string
Age int
Height float64
}
func main() {
tstObj := testObject{Name: "yog prakash", Age: 24, Height: 5.6}
val := reflect.ValueOf(&tstObj).Elem()
typeOfTstObj := val.Type()
for i := 0; i < val.NumField(); i++ {
fieldType := val.Field(i)
fmt.Printf("object field %d key=%s value=%v type=%s \n",
i, typeOfTstObj.Field(i).Name, fieldType.Interface(),
fieldType.Type())
}
}
Output
object field 0 key=Name value=yog prakash type=string
object field 1 key=Age value=24 type=int
object field 2 key=Height value=5.6 type=float64
See in IDE https://play.golang.org/p/bwIpYnBQiE

You can use: interface{}..(type) as in this playground
package main
import "fmt"
func main(){
types := []interface{} {"a",6,6.0,true}
for _,v := range types{
fmt.Printf("%T\n",v)
switch v.(type) {
case int:
fmt.Printf("Twice %v is %v\n", v, v.(int) * 2)
case string:
fmt.Printf("%q is %v bytes long\n", v, len(v.(string)))
default:
fmt.Printf("I don't know about type %T!\n", v)
}
}
}

For arrays and slices use Type.Elem():
a := []string{"foo", "bar", "baz"}
fmt.Println(reflect.TypeOf(a).Elem())

I have organized the following.
fmt %T : a Go-syntax representation of the type of the value
reflect.TypeOf.String()
reflect.TypeOf.Kind()
type assertions
Example
package _test
import (
"fmt"
"reflect"
"testing"
)
func TestType(t *testing.T) {
type Person struct {
name string
}
var i interface{}
i = &Person{"Carson"}
for idx, d := range []struct {
actual interface{}
expected interface{}
}{
{fmt.Sprintf("%T", "Hello") == "string", true},
{reflect.TypeOf("string").String() == "string", true},
{reflect.TypeOf("string").Kind() == reflect.String, true},
{reflect.TypeOf(10).String() == "int", true},
{reflect.TypeOf(10).Kind() == reflect.Int, true},
{fmt.Sprintf("%T", 1.2) == "float64", true},
{reflect.TypeOf(1.2).String() == "float64", true},
{reflect.TypeOf(1.2).Kind() == reflect.Float64, true},
{reflect.TypeOf([]byte{3}).String() == "[]uint8", true},
{reflect.TypeOf([]byte{3}).Kind() == reflect.Slice, true},
{reflect.TypeOf([]int8{3}).String() == "[]int8", true},
{reflect.TypeOf([]int8{3}).Kind() == reflect.Slice, true},
{reflect.TypeOf(Person{"carson"}).Kind() == reflect.Struct, true},
{reflect.TypeOf(&Person{"carson"}).Kind() == reflect.Ptr, true},
{fmt.Sprintf("%v", i.(*Person)) == "&{Carson}", true},
{fmt.Sprintf("%+v", i.(*Person)) == "&{name:Carson}", true},
} {
if d.actual != d.expected {
t.Fatalf("%d | %s", idx, d.actual)
}
}
}
go playground

In case if you want to detect the type within if expression:
if str, ok := myvar.(string); ok {
print("It's a string")
}
Or without type assertion (may produce errors):
if reflect.TypeOf(myvar).String() == "string" {
print("It's a string")
}

you can use reflect.TypeOf.
basic type(e.g.: int, string): it will return its name (e.g.: int, string)
struct: it will return something in the format <package name>.<struct name> (e.g.: main.test)

reflect package comes to rescue:
reflect.TypeOf(obj).String()
Check this demo

Related

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)
}

Appending to go lang slice using reflection

For some reason, it appears that adding new element to slice using reflection doesn't update slice itself. This is the code to demonstrate:
package main
import (
"fmt"
"reflect"
)
func appendToSlice(arrPtr interface{}) {
valuePtr := reflect.ValueOf(arrPtr)
value := valuePtr.Elem()
value = reflect.Append(value, reflect.ValueOf(55))
fmt.Println(value.Len()) // prints 1
}
func main() {
arr := []int{}
appendToSlice(&arr)
fmt.Println(len(arr)) // prints 0
}
Playground link : https://play.golang.org/p/j3532H_mUL
Is there something I'm missing here?
reflect.Append works like append in that it returns a new slice value.
You are assigning this value to the value variable in the appendToSlice function, which replaces the previous reflect.Value, but does not update the original argument.
To make it more clear what's happening, take the equivalent function to your example without reflection:
func appendToSlice(arrPtr *[]int) {
value := *arrPtr
value = append(value, 55)
fmt.Println(len(value))
}
What you need to use is the Value.Set method to update the original value:
func appendToSlice(arrPtr interface{}) {
valuePtr := reflect.ValueOf(arrPtr)
value := valuePtr.Elem()
value.Set(reflect.Append(value, reflect.ValueOf(55)))
fmt.Println(value.Len())
}
https://play.golang.org/p/Nhabg31Sju
package main
import "fmt"
import "reflect"
type Foo struct {
Name string
}
func main() {
_type := []Foo{}
fmt.Printf("_type: v(%v) T(%T)\n", _type, _type)
reflection := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(_type).Elem()), 0, 0)
reflectionValue := reflect.New(reflection.Type())
reflectionValue.Elem().Set(reflection)
slicePtr := reflect.ValueOf(reflectionValue.Interface())
sliceValuePtr := slicePtr.Elem()
sliceValuePtr.Set(reflect.Append(sliceValuePtr, reflect.ValueOf(Foo{"a"})))
sliceValuePtr.Set(reflect.Append(sliceValuePtr, reflect.ValueOf(Foo{"b"})))
sliceValuePtr.Set(reflect.Append(sliceValuePtr, reflect.ValueOf(Foo{"c"})))
values := []Foo{Foo{"d"}, Foo{"e"}}
for _, val := range values {
sliceValuePtr.Set(reflect.Append(sliceValuePtr, reflect.ValueOf(val)))
}
result := sliceValuePtr.Interface()
fmt.Printf("result: %T = (%v)\n", result, result)
}
take a look at: https://play.golang.org/p/vXOqTVSEleO

Iterate through struct in golang without reflect

I have a struct like this
import (
"fmt"
)
type Node struct {
m []string
o []string
}
func main() {
var mm = []string{"abc", "def"}
var oo = []string{"111", "222"}
var v = Node{m: mm, o: oo}
for _, d := range []interface{}{v.m, v.o} {
fmt.Println(d)
}
}
The output I get is,
[abc def]
[111 222]
My desired output is,
abc,111
def,222
I don't want to use reflect package because, I want to use native go built-ins as much as possible. If it becomes too burdensome I will fall back on reflect package.
Edit: I just realized my output doesn't match yours, do you want the letters paired with the numbers? If so then you'll need to re-work what you have.
You can use strings.Join and a type switch statement to accomplish this:
https://play.golang.org/p/ygtdxv02uK
package main
import (
"fmt"
"strings"
)
type Node struct {
m []string
o []string
p []int
}
func main() {
var mm = []string{"abc", "def"}
var oo = []string{"111", "222"}
var pp = []int{1, 2, 3}
var v = Node{m: mm, o: oo, p: pp}
for _, d := range []interface{}{v.m, v.o, v.p} {
switch d.(type) {
case []string:
fmt.Println(strings.Join(d.([]string), ","))
default:
fmt.Println(d)
}
}
}
The output is:
abc,def
111,222
[1 2 3]
Is there a reason you don't want to use the reflect package? like Iterate through a struct in Go and Iterate Over String Fields in Struct ?
From the former question, it seems like, yeah you can iterate without reflect by iterating through an interface of the fields, https://play.golang.org/p/bPWUII_D7q
package main
import (
"fmt"
)
type Foo struct {
num int
str string
}
func main() {
foo := &Foo{42, "Hello"} // struct with fields of many types...
for _, data := range []interface{}{foo.num, foo.str} {
fmt.Println(data)
}
}
Here is what I did,
package main
import (
"fmt"
)
type Node struct {
m []string
o []string
}
func main() {
var mm = []string{"abc", "def"}
var oo = []string{"111", "222"}
var v = Node{m: mm, o: oo}
for i := range v.m {
fmt.Println(v.m[i],v.o[i])
}
}
This gives me my desired output. Just one thing is I have to write v.m so I suppose I should still use reflect package.

Get rid of empty JSON values from map of interface{}

I have a struct in which I put all excess data into a map[string]interface{}.
If I unmarshal into the Data property with an empty variable, I don't want to keep it when marshalling. I basically need interface{} to have json:",omitempty", How do I get that?
type Event struct {
From string `json:"from"`
Data map[string]interface{} `json:"data,omitempty"`
}
The omitempty is for encoding values, but not for decoding.
You cannot generate a complete empty map in Go. (Empty as in, it does not exists.) If your create a variable / value of a struct it always has its default value.
package main
import "fmt"
func main() {
var m map[string]interface{}
fmt.Printf("%v %d\n", m, len(m))
// prints: map[] 0
m = nil
fmt.Printf("%v %d\n", m, len(m))
// prints: map[] 0
}
Example: Go Playground.
I'd like to know if there's anything native that supports it. However until then, you can do it via reflection:
package main
import (
"encoding/json"
"fmt"
"reflect"
)
func main() {
m := map[string]interface{}{
"should_exist": "foo",
"should_omit": "",
}
for k, v := range m {
if reflect.ValueOf(v).IsZero() {
delete(m, k)
}
}
data, _ := json.Marshal(m)
fmt.Println(string(data)) // {"should_exist":"foo"}
}
Please note the performance hit this might cause in some use cases.

How to get a list of values into a flag in Golang?

What is Golang's equivalent of the below python commands ?
import argparse
parser = argparse.ArgumentParser(description="something")
parser.add_argument("-getList1",nargs='*',help="get 0 or more values")
parser.add_argument("-getList2",nargs='?',help="get 1 or more values")
I have seen that the flag package allows argument parsing in Golang.
But it seems to support only String, Int or Bool.
How to get a list of values into a flag in this format :
go run myCode.go -getList1 value1 value2
You can define your own flag.Value and use flag.Var() for binding it.
The example is here.
Then you can pass multiple flags like following:
go run your_file.go --list1 value1 --list1 value2
UPD: including code snippet right there just in case.
package main
import "flag"
type arrayFlags []string
func (i *arrayFlags) String() string {
return "my string representation"
}
func (i *arrayFlags) Set(value string) error {
*i = append(*i, value)
return nil
}
var myFlags arrayFlags
func main() {
flag.Var(&myFlags, "list1", "Some description for this param.")
flag.Parse()
}
You can at least have a list of arguments on the end of you command by using the flag.Args() function.
package main
import (
"flag"
"fmt"
)
var one string
func main() {
flag.StringVar(&one, "o", "default", "arg one")
flag.Parse()
tail := flag.Args()
fmt.Printf("Tail: %+q\n", tail)
}
my-go-app -o 1 this is the rest will print Tail: ["this" "is" "the" "rest"]
Use flag.String() to get the entire list of values for the argument you need and then split it up into individual items with strings.Split().
If you have a series of integer values at the end of the command line, this helper function will properly convert them and place them in a slice of ints:
package main
import (
"flag"
"fmt"
"strconv"
)
func GetIntSlice(i *[]string) []int {
var arr = *i
ret := []int{}
for _, str := range arr {
one_int, _ := strconv.Atoi(str)
ret = append(ret, one_int)
}
return ret
}
func main() {
flag.Parse()
tail := flag.Args()
fmt.Printf("Tail: %T, %+v\n", tail, tail)
intSlice := GetIntSlice(&tail)
fmt.Printf("intSlice: %T, %+v\n", intSlice, intSlice)
}
mac:demoProject sx$ go run demo2.go 1 2 3 4
Tail: []string, [1 2 3 4]
intSlice: []int, [1 2 3 4]

Resources