理解golang的interface主要在于如下两点:golang
package main import "fmt" type Animal interface { Speak() string } type Cat struct{} func (c *Cat) Speak() string { return "cat" } type Dog struct{} func (d Dog) Speak() string { return "dog" } func main() { animals := []Animal{Cat{}, Dog{}} for _, animal := range animals { fmt.Println(animal.Speak()) } }
以上代码中,定义了Animal为接口,而Cat和Dog两个结构体分别实现了接口中定义的方法。当interface{}做为函数形参时,能够接受不一样类型的参数。数组
若是将上述代码的:函数
func (c Cat) Speak() string { return "cat" }
修改成:指针
func (c *Cat) Speak() string { return "cat" }
再次运行源代码,就会出现如下错误:code
cannot use Cat literal (type Cat) as type Animal in array or slice literal: Cat does not implement Animal (Speak method has pointer receiver)
这是由于程序认为Cat并未实现Speak()方法, 而是由 *Cat 实现的。这说明结构体在实现接口方法时并不会隐式转换类型。接口
可是:string
可是,把 animals := []Animal{Cat{}, Dog{}} 修改为 animals := []Animal{&Cat{}, &Dog{}} 却能够执行,由于把指针做为参数,会隐式转换。
interface{} 做为函数形参和 []interface{} 做为形参有很大区别,示例以下:it
interface{} 能够赋值任何类型的值class
package main import "fmt" func Test(params interface{}) { fmt.Println(params) } func main() { Test("string") Test(123) Test(true) }
package main import ( "fmt" ) func PrintAll(vals []interface{}) { for _, val := range vals { fmt.Println(val) } } func main() { names := []string{"stanley", "david", "oscar"} PrintAll(names) }
以上代码是没法正常运行的,错误提示为:import
cannot use names (type []string) as type []interface {} in argument to PrintAll
这说明对接口数组赋值前,必须多一个类型转换操做,正确代码以下:
package main import ( "fmt" ) func PrintAll(vals []interface{}) { for _, val := range vals { fmt.Println(val) } } func main() { names := []string{"stanley", "david", "oscar"} vals := make([]interface{}, len(names)) for i, v := range names { vals[i] = v } PrintAll(vals) }