Code
interfaceMap := make(map[string]interface{})
interfaceMap["number"] = 1
interfaceMap["text"] = "two"
interfaceMap["list"] = []int{3, 4}
interfaceMap["map"] = map[string]interface{}{
"more": 12345,
}
interfaceMap["struct"] = struct {
string
int
}{
"number",
1,
}
if _, ok := interfaceMap["number"].(string); !ok {
fmt.Println("1 is not a string")
}
if i, ok := interfaceMap["number"].(int); ok {
fmt.Printf("but %d is an integer\n", i)
}
if l, ok := interfaceMap["list"].([]int); ok {
fmt.Printf("l is a list. Its elements are %v\n", l)
fmt.Printf("The first element in the list is %d\n", l[0])
}
fmt.Printf("The type of interface object with the \"map\" key is %T\n", interfaceMap["map"])
if m, ok := interfaceMap["map"].(map[string]interface{}); ok {
fmt.Println("This is a complicated type")
fmt.Printf("The type of interfaceMap[\"map\"][\"more\"] is %T, and the value is %d\n", m["more"], m["more"].(int))
}
fmt.Printf("For the one with the \"struct\" key, it's %T\n", interfaceMap["struct"])
theStruct := interfaceMap["struct"].(struct {
string
int
})
fmt.Printf("The struct values are %s and %d\n", theStruct.string, theStruct.int)
Output
1 is not a string
but 1 is an integer
l is a list. Its elements are [3 4]
The first element in the list is 3
The type of interface object with the "map" key is map[string]interface {}
This is a complicated type
The type of interfaceMap["map"]["more"] is int, and the value is 12345
For the one with the "struct" key, it's struct { string; int }
The struct values are number and 1
More Code
result, _ := add(0.5, 1)
fmt.Printf("First result: %f, type: %v\n", result, reflect.TypeOf(result))
result, _ = add(2, int8(3))
fmt.Printf("Second result: %d, type: %v\n", result, reflect.TypeOf(result))
result, _ = add("s", "t")
fmt.Printf("Third result: %s, type: %v\n", result, reflect.TypeOf(result))
_, err := add(2, "five")
fmt.Println(err.Error())
func add(v1 interface{}, v2 interface{}) (interface{}, error) {
rt1 := reflect.TypeOf(v1)
rt2 := reflect.TypeOf(v2)
rv1 := reflect.ValueOf(v1)
rv2 := reflect.ValueOf(v2)
if rt1.Kind() == reflect.String && rt2.Kind() == reflect.String {
return rv1.String() + rv2.String(), nil
}
if rv1.CanFloat() && rv2.CanFloat() {
return rv1.Float() + rv2.Float(), nil
}
if rv1.CanInt() && rv2.CanInt() {
return rv1.Int() + rv2.Int(), nil
}
if rv1.CanFloat() && rv2.CanInt() {
return rv1.Float() + float64(rv2.Int()), nil
}
if rv1.CanInt() && rv2.CanFloat() {
return float64(rv1.Int()) + rv2.Float(), nil
}
return nil, fmt.Errorf("Adding values of type %s and %s is not supported", rt1.Kind(), rt2.Kind())
}
Output
First result: 1.500000, type: float64
Second result: 5, type: int64
Third result: st, type: string
Adding values of type int and string is not supported