三 空接口
接口类型的一个极端重要的例子是空接口:interface{} ,它表示空的方法集合,由于任何值都有零个或者多个方法,所以任何值都可以满足它。 注意,[]T不能直接赋值给[]interface{}
//t := []int{1, 2, 3, 4} wrong
//var s []interface{} = t
t := []int{1, 2, 3, 4} //right
s := make([]interface{}, len(t))
for i, v := range t {
s[i] = v
}
str, ok := value.(string)
if ok {
fmt.Printf("string value is: %qn", str)
} else {
fmt.Printf("value is not a stringn")
}
在Go语言中,我们可以使用type switch语句查询接口变量的真实数据类型,语法如下:
type Stringer interface {
String() string
}
var value interface{} // Value provided by caller.
switch str := value.(type) {
case string:
return str //type of str is string
case Stringer: //type of str is Stringer
return str.String()
}
也可以使用“comma, ok”的习惯用法来安全地测试值是否为一个字符串:
str, ok := value.(string)
if ok {
fmt.Printf("string value is: %qn", str)
} else {
fmt.Printf("value is not a stringn")
}
四 接口赋值
package main
import (
"fmt"
)
type LesssAdder interface {
Less(b Integer) bool
Add(b Integer)
}
type Integer int
func (a Integer) Less(b Integer) bool {
return a < b
}
func (a *Integer) Add(b Integer) {
*a += b
}
func main() {
var a Integer = 1
var b LesssAdder = &a
fmt.Println(b)
//var c LesssAdder = a
//Error:Integer does not implement LesssAdder
//(Add method has pointer receiver)
}
go语言可以根据下面的函数:
func (a Integer) Less(b Integer) bool
自动生成一个新的Less()方法
func (a *Integer) Less(b Integer) bool
这样,类型*Integer就既存在Less()方法,也存在Add()方法,满足LessAdder接口。 而根据
func (a *Integer) Add(b Integer)
这个函数无法生成以下成员方法:
func(a Integer) Add(b Integer) {
(&a).Add(b)
}
因为(&a).Add()改变的只是函数参数a,对外部实际要操作的对象并无影响(值传递),这不符合用户的预期。所以Go语言不会自动为其生成该函数。因此类型Integer只存在Less()方法,缺少Add()方法,不满足LessAddr接口。(可以这样去理解:指针类型的对象函数是可读可写的,非指针类型的对象函数是只读的)将一个接口赋值给另外一个接口 在Go语言中,只要两个接口拥有相同的方法列表(次序不同不要紧),那么它们就等同的,可以相互赋值。 如果A接口的方法列表时接口B的方法列表的子集,那么接口B可以赋值给接口A,但是反过来是不行的,无法通过编译。










