我的 Go 语言学习之旅(接口)
Go语言中的接口
基础知识
空的接口
接口值
类型断言
类型开关
实现接口
Go语言中的接口
在 Go 语言中,接口interface是一组方法签名。接口类型的变量可以保存任何实现了这些方法的值。
基础知识
你可以像下面的代码一样声明一个interface方法。它本质上就是一个方法列表。
type NAME_OF_INTERFACE interface {
method_name1(return_type1)
method_name2(return_type2)
..........
method_namex(return_typex)
}
任何提供了接口中指定方法的类型都被视为该接口的实现,无需显式声明。
空的接口
不指定任何方法的接口类型称为无方法接口empty interface。它可以定义为以下代码。
interface {}
空接口类型的变量可以保存任何类型的值。
package main
import "fmt"
func main(){
var intface interface{}
intface = 1
fmt.Println(intface) //=> 1
intface = "string" //=> string
fmt.Println(intface)
intface = []string{"Go", "Ruby", "JS"}
fmt.Println(intface) //=>[Go Ruby JS]
}
接口值
Ainterface value表示为一个具体值和一个动态类型的对。
[Value, Type]
你可以使用%v`print` 函数打印具体值,也可以使用%T`print` 函数打印动态类型。
package main
import "fmt"
func main(){
var intface interface{}
intface = 1
fmt.Printf("%v %T\n", intface, intface) //=>1 int
intface = "string"
fmt.Printf("%v %T\n", intface, intface) //=> string string
intface = []string{"Go", "Ruby", "JS"}
fmt.Printf("%v %T\n", intface, intface) //=> [Go Ruby JS] []string
}
类型断言
Atype assertion提供对接口值的底层具体值的访问。
concrete_value := Interface_value.(TYPE)
上述语句断言接口Interface_value持有具体类型TYPE,并将底层TYPE值赋给它variable。
要检查接口值是否持有特定类型,type assertion可以返回两个值:一个是断言结果underlying value,另一个boolean value是报告断言是否成功的值。
concrete_value, ok := Interface_value.(TYPE)
package main
import "fmt"
func main(){
var intface interface{} = "Hello World"
t := intface.(string)
fmt.Println(t) //=> Hello World
t2, ok := intface.(string)
fmt.Println(t2, ok) //=> Hello World true
t3, ok := intface.(float64)
fmt.Println(t3, ok) //=> 0 false
}
类型开关
Atype switch是一种允许连续进行多个类型断言的结构。您可以像以下代码一样
声明A。type switch
switch v := x.(type) {
case TYPE1:
//here v has TYPE1
case TYPE2:
//here: v has TYPE2
...
default: ...
}
在以下代码中,switch 语句测试接口值是否i包含类型为 ` intT` 或 `C`的值。在 `T` 和 ` C`string两种情况下,变量 `T`将分别具有 `T`或`C` 的类型,并保存 `T` 的值。 在默认情况下(没有匹配项),变量 `T`的接口类型和值与 `T` 相同。intstringvintstringivi
package main
import "fmt"
func typeSwitch(i interface{}) {
switch v := i.(type) {
case int:
fmt.Printf("Twice %v is %v\n", v, v*2)
case string:
fmt.Printf("%q is %v bytes long\n", v, len(v))
default:
fmt.Printf("I don't know about type %T!\n", v)
}
}
func main() {
typeSwitch(21) //=> Twice 21 is 42
typeSwitch("Hello World") //=> "Hello World" is 11 bytes long
typeSwitch(true)//=> I don't know about type bool!
}
实现接口
Interfaces可以像下面的代码一样,作为结构体的方法来实现。
package main
import "fmt"
type People interface {
intro()
}
type Person struct {
name string
}
func (rarg Person) intro() string{
return "Hello" + " " + "I'm" + " " + rarg.name
}
func main() {
bob := Person{"Bob"}
fmt.Println(bob.intro()) //=> Hello I'm Bob
}