扫码一下
查看教程更方便
在 go 中,可以认为接口是一组方法的集合。当一个类型实现了接口中的所有方法时,就说它实现了接口。它与 oop 世界非常相似。接口指定类型应该具有哪些方法,类型决定如何实现这些方法。
接口的声明语法如下
type interface_name interface {
method_name1 [return_type]
method_name2 [return_type]
method_name3 [return_type]
...
method_namen [return_type]
}
让我们直接创建接口并实现它。
package main
import (
"fmt"
)
//接口定义
type vowelsfinder interface {
findvowels() []rune
}
type mystring string
//mystring 实现vowelsfinder接口
func (ms mystring) findvowels() []rune {
var vowels []rune
for _, rune := range ms {
if rune == 'a' || rune == 'e' || rune == 'i' || rune == 'o' || rune == 'u' {
vowels = append(vowels, rune)
}
}
return vowels
}
func main() {
name := mystring("sam anderson")
var v vowelsfinder
v = name
fmt.printf("元音字符是 %c", v.findvowels())
}
上述代码执行结果如下
元音字符是 [a e o]
上面的例子教我们如何创建和实现接口,但它并没有真正展示接口的实际用途。
如果我们在上面的程序中使用 name.findvowels()而不是 v.findvowels(),也能输出相同的结果,但是这样并不会使用接口。
现在让我们看一个接口的实际使用的示例。
我们将编写一个简单的程序,根据员工的个人工资计算公司的总费用。
package main
import (
"fmt"
)
// 定义一个接口
type salarycalculator interface {
calculatesalary() int
}
type permanent struct {
empid int
basicpay int
pf int
}
type contract struct {
empid int
basicpay int
}
// 永久员工的薪资是 basicpay 与 pf 的和
func (p permanent) calculatesalary() int {
return p.basicpay p.pf
}
// 合同工只有basicpay
func (c contract) calculatesalary() int {
return c.basicpay
}
// 通过迭代salarycalculator 切片,计算员工的薪资综合,从而计算出公司的总花费
func totalexpense(s []salarycalculator) {
expense := 0
for _, v := range s {
expense = expense v.calculatesalary()
}
fmt.printf("每个月总花费: $%d", expense)
}
func main() {
pemp1 := permanent{
empid: 1,
basicpay: 5000,
pf: 20,
}
pemp2 := permanent{
empid: 2,
basicpay: 6000,
pf: 30,
}
cemp1 := contract{
empid: 3,
basicpay: 3000,
}
employees := []salarycalculator{pemp1, pemp2, cemp1}
totalexpense(employees)
}
上述代码执行结果如下
每个月总花费: $14050
对于上例来说,使用接口的优势在于:
totalexpense
可以扩展到任何新员工类型而无需任何代码更改。假设公司增加了freelancer
一种工资结构不同的新型员工。可以只是将freelancer
在 slice 参数中传递给totalexpense()
方法, 而无需对函数totalexpense
进行任何一行代码更改。