Golang Interface Examples

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

Leave a Reply