从接口的声明语法type InterfaceName interface {}也可以看出来,Golang中的接口本质上也是一种数据类型,既然是一种数据类型,我们就可以声明该类型的变量,比如var v VowelsFinder,然后我们会给该变量赋值,比如前面的:
name := MyString("Sam Anderson")
var v VowelsFinder
v = name
因此接口类型变量v内部有一个具体数据类型MyString和具体值"Sam Anderson"。
我们实现一个例子来理解下:
package main
import "fmt"
type Tester interface {
Test()
}
type MyFloat float64
func (m MyFloat) Test() {
fmt.Println(m)
}
func describe(t Tester) {
fmt.Printf("Interface type %T value %v\n", t, t)
}
func main() {
var t Tester
f := MyFloat(89.7)
t = f
describe(t)
t.Test()
}
这里的接口Tester含有一个方法签名Test()。我们声明了一个该接口类型的变量var t Tester,由于MyFloat类型实现了该接口,因此我们将MyFloat类型的变量f赋值给变量t,这时t内部的具体类型即为MyFloat,具体值即为89.7。describe函数打印出了具体类型和具体值。该程序输出结果如下:
package main
import "fmt"
func findType(i interface{}) {
switch i.(type) {
case string:
fmt.Printf("I am a string and my value is %s\n", i.(string))
case int:
fmt.Printf("I am a int and my value is %d\n", i.(int))
default:
fmt.Printf("Unknown type\n")
}
}
func main() {
findType("Naveen")
findType(77)
findType(89.98)
}
package main
import "fmt"
type User interface {
SetIndex(int)
}
type UserMutable struct {
Index int
}
// UserMutable DOES NOT implement User, *UserMutable implements User
func (u *UserMutable) SetIndex(index int) {
u.Index = index
}
type UserImmutable struct {
Index int
}
// UserImmutable implements User
func (u UserImmutable) SetIndex(index int) {
u.Index = index
}
func main() {
//userMutable is type *UserMutable
userMutable := &UserMutable{1}
// but not userMutable := UserMutable{1}
var user User
user = userMutable // 这时user内部具体类型是指针类型
user.SetIndex(9)
//userImmutable is type UserImmutable
userImmutable := UserImmutable{1}
// or userImmutable := &UserImmutable{1}
var user2 User
user2 = userImmutable
user2.SetIndex(9)
fmt.Println("userMutable", userMutable.Index)
// "userMutable 9"
fmt.Println("userImmutable", userImmutable.Index)
// "userImmutable 1"
}
userMutable := &UserMutable{1}
// but not userMutable := UserMutable{1}
var user User
user = userMutable
前面的程序输出如下:
userMutable 9
userImmutable 1
实现多个接口
Golang中一个类型可以实现多个接口,我们举个例子:
package main
import "fmt"
type SalaryCalculator interface {
DisplaySalary()
}
type LeaveCalculator interface {
CalculateLeavesLeft() int
}
type Employee struct {
firstName string
lastName string
basicPay int
pf int
totalLeaves int
leavesTaken int
}
func (e Employee) DisplaySalary() {
fmt.Printf("%s %s has salary $%d", e.firstName, e.lastName, (e.basicPay + e.pf))
}
func (e Employee) CalculateLeavesLeft() int {
return e.totalLeaves - e.leavesTaken
}
func main() {
e := Employee{
firstName: "Naveen",
lastName: "Ramanathan",
basicPay: 5000,
pf: 200,
totalLeaves: 30,
leavesTaken: 5,
}
var s SalaryCalculator = e
s.DisplaySalary()
var l LeaveCalculator = e
fmt.Println("\nLeaves left =", l.CalculateLeavesLeft())
}
package main
import "fmt"
type Describer interface {
Describe()
}
func main() {
var d1 Describer
if d1 == nil {
fmt.Printf("d1 is nil and has type %T value %v\n", d1, d1)
}
}