详解Golang语言中的interface
程序员文章站
2022-03-28 17:51:49
interface是一组method签名的组合,interface可以被任意对象实现,一个对象也可以实现多个interface。任意类型都实现了空interface(也就是包含0个method的int...
interface是一组method签名的组合,interface可以被任意对象实现,一个对象也可以实现多个interface。任意类型都实现了空interface(也就是包含0个method的interface),空interface可以存储任意类型的值。interface定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了此接口。
go version go1.12
package main import ( "fmt" ) // 定义struct type human struct { name string age int phone string } type student struct { human // 匿名字段 school string loan float32 } type employee struct { human // 匿名字段 company string money float32 } // human对象实现sayhi()方法 func (h human) sayhi() { fmt.printf("hi, i am %s, you can call me on %s\n", h.name, h.phone) } // human对象实现sing()方法 func (h human) sing(lyrics string) { fmt.println("la la la...", lyrics) } // human对象实现guzzle()方法 func (h human) guzzle(beerstein string) { fmt.println("guzzle guzzle guzzle...", beerstein) } // employee对象重写sayhi()方法 func (e employee) sayhi() { fmt.printf("hi i am %s, i work at %s. call me on %s\n", e.name, e.company, e.phone) } // student对象实现borrowmoney()方法 func (s student) borrowmoney(amount float32) { s.loan += amount } // employee对象实现spendsalary()方法 func (e employee) spendsalary(amount float32) { e.money -= amount } // 定义interface,interface是一组method签名的组合 // interface可以被任意对象实现,一个对象也可以实现多个interface // 任意类型都实现了空interface(也就是包含0个method的interface) // 空interface可以存储任意类型的值 // interface men的3个method被human,student,employee实现,也就是这3个对象都实现了interface men。即: // interface定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了此接口。 type men interface { sayhi() sing(lyrice string) guzzle(beerstein string) } // interface youngchap的borrowmoney() method只被student对象实现,也就是只有student实现了youngchap type youngchap interface { sayhi() sing(song string) borrowmoney(amount float32) } // interface elderlygent的spendsalary() method只被employee对象实现,也就是只有employee实现了elderlygent type elderlygent interface { sayhi() sing(song string) spendsalary(amount float32) } func main() { // 定义student类型的变量 lucy := student{human{"lucy", 19, "10086"}, "tsinghua", 100.00} lily := student{human{"lily", 19, "10086"}, "tsinghua", 100.00} liming := student{human{"liming", 19, "10086"}, "tsinghua", 100.00} // 定义employee类型的变量 tom := employee{human{"tom", 29, "10000"}, "google", 200.00} // 定义men类型的变量i var i men // i存储student i = lucy fmt.println("this is lucy, a student:") i.sayhi() i.sing("happy birthday") i.guzzle("ha ha ha...") // i存储employee i = tom fmt.println("this is tom, an employee:") i.sayhi() // 定义slice men,包含men类型元素的切片,这个slice可以被赋予实现了men接口的任意结构的对象 fmt.println("let's use a slice of men and see what happens:") x := make([]men, 3) // 三个不同类型(不同method)的元素,实现了同一个interface(men) x[0], x[1], x[2] = lucy, lily, liming for _, value := range x { value.sayhi() } }
函数参数
interface接口还可以作为函数参数,因为interface的变量可以持有任意实现该interface类型的对象,我们可以通过定义interface参数,让函数接受各种类型的参数。 判断interface变量存储的元素的类型,目前常用的有两种方法:comma-ok断言和switch测试。
go version go1.12
/** * interface接口作为函数参数 * 判断interface变量存储的元素的类型 */ package main import ( "fmt" "strconv" ) // 定义human对象 type human struct { name string age int phone string } // 定义空接口 type element interface{} // 定义切片 type list []element // 定义person对象 type person struct { name string age int } // 通过定义interface参数,让函数接受各种类型的参数 // 通过这个method(方法),human对象实现了fmt.stringer接口 // stringer接口是fmt.println()的参数,最终使得human对象可以作为fmt.println的参数被调用 func (h human) string() string { return "<" + h.name + " - " + strconv.itoa(h.age) + " years - phone: " + h.phone + ">" } // 通过定义interface参数,让函数接受各种类型的参数 // 通过这个method(方法),person对象实现了fmt.stringer接口 // stringer接口是fmt.println()的参数,最终使得person对象可以作为fmt.println的参数被调用 func (p person) string() string { return "(name: " + p.name + " - age: " + strconv.itoa(p.age) + " years)" } func main() { // interface作为函数的参数传递 lucy := human{"lucy", 29, "10086"} fmt.println("this human is:", lucy) list := make(list, 3) list[0] = 100 list[1] = "hello golang!" list[2] = person{"lily", 19} // comma-ok断言 for index, element := range list { // 判断变量的类型 格式:value, ok = element(t) // value是interface变量的值,ok是bool类型,element是interface的变量,t是断言的interface变量的类型 if value, ok := element.(int); ok { fmt.printf("list[%d] is an int and it's value is %d\n", index, value) } else if value, ok := element.(string); ok { fmt.printf("list[%d] is a string and it's value is %s\n", index, value) } else if value, ok := element.(person); ok { fmt.printf("list[%d] is a person and it's value is %s\n", index, value) } else { fmt.printf("list[%d] is a different type\n", index) } } // switch for index, element := range list { // 注意:element.(type)语法不能在switch外的任何逻辑中使用 switch value := element.(type) { case int: fmt.printf("list[%d] is an int, it's value is %d\n", index, value) case string: fmt.printf("list[%d] is a string, it's value is %s\n", index, value) case person: fmt.printf("list[%d] is a person, it's value is %s\n", index, value) default: fmt.printf("list[%d] is a differernt type", index) } } }
以上就是详解golang语言中的interface的详细内容,更多关于golang语言中的interface的资料请关注其它相关文章!