Golang 中的接口是一种抽象数据类型,Golang 中接口定义了对象的行为规范,只定义规范 不实现。接口中定义的规范由具体的对象来实现。
通俗的讲接口就一个标准,它是对一个对象的行为和规范进行约定,约定实现接口的对象必 须得按照接口的规范。
在 Golang 中接口(interface)是一种类型,一种抽象的类型。接口(interface)是一组 函数 method 的集合,Golang 中的接口不能包含任何变量。 在 Golang 中接口中的所有方法都没有方法体,接口定义了一个对象的行为规范,只定 义规范不实现。接口体现了程序设计的多态和高内聚低耦合的思想 Golang 中的接口也是一种数据类型,不需要显示实现。只需要一个变量含有接口类型 中的所有方法,那么这个变量就实现了这个接口。
Go中每个接口由数个方法组成,接口的定义格式如下:
type 接口名 interface{
方法名 1( 参数列表 1 ) 返回值列表 1
方法名 2( 参数列表 2 ) 返回值列表 2
…
}
其中:
- 接口名:使用 type 将接口定义为自定义的类型名。Go 语言的接口在命名时,一般会在 单词后面添加 er,如有写操作的接口叫 Writer,有字符串功能的接口叫 Stringer 等。接 口名最好要能突出该接口的类型含义。
- 方法名:当方法名首字母是大写且这个接口类型名首字母也是大写时,这个方法可以被 接口所在的包(package)之外的代码访问。
- 参数列表、返回值列表:参数列表和返回值列表中的参数变量名可以省略。
(1)定义一个 Usber 接口让 Phone 和 Camera 结构体实现这个接口。
package main
import "fmt"
//接口是一个规范
type Usber interface {
Start()
Stop()
}
//如果接口里面有方法的话,必须要通过结构体或者自定义类型来实现这个接口
type Phone struct {
Name string
}
func (p Phone) Start() {
fmt.Println(p.Name, "开始工作")
}
func (p Phone) Stop() {
fmt.Println("phone 停止")
}
type Camera struct {
}
func (c Camera) Start() {
fmt.Println("相机 开始工作")
}
func (c Camera) Stop() {
fmt.Println("相机 停止工作")
}
func main() {
phone := Phone{ Name: "小米手机", }
var p Usber = phone //phone 实现了 Usb 接口
p.Start()
camera := Camera{}
var c Usber = camera //camera 实现了 Usb 接口
c.Start()
}
(2)Computer 结构体中的 Work 方法必须传入一个 Usb 的接口
package main
import (
"fmt"
)
//接口是一个类型
type Usber interface {
start()
stop()
}
//电脑
type Computer struct {
}
//手机
type Phone struct {
Name string
}
//相机
type Camera struct{}
func (c Computer) work(usb Usber) {
usb.start()
usb.stop()
}
func (p Phone) start() {
fmt.Println(p.Name + "启动")
}
func (p Phone) stop() {
fmt.Println(p.Name + "关机")
}
func (c Camera) start() {
fmt.Println("相机启动")
}
func (c Camera) stop() {
fmt.Println("相机关机")
}
func main() {
p := Phone{
Name: "苹果手机",
}
var p1 Usber = p //表示手机实现usb接口
p1.stop()
p1.start()
fmt.Printf("%Tn", p1)
computer := Computer{}
camera := Camera{}
computer.work(p)
computer.work(camera)
}
4.空接口
(1)概念
Golang 中的接口可以不定义任何方法,没有定义任何方法的接口就是空接口。
空接口表示没有任何约束,因此任何类型变量都可以实现空接口。 空接口在实际项目中用的是非常多的,用空接口可以表示任意数据类型。
package main
import "fmt"
type A interface{} //空接口表示没有任何约束,任意的类型都可以实现空接口
func main() {
var str = "golang"
var a A = str //让string类型实现A这个接口
fmt.Printf("值:%v 类型:%Tn", a, a)
var num = 10
a = num //让int类型实现A这个接口
fmt.Printf("值:%v 类型:%Tn", a, a)
var flag = true
a = flag //让bool类型实现A这个接口
fmt.Printf("值:%v 类型:%Tn", a, a)
}
另外,Go中空接口也可以直接当做类型来使用,可以表示任意类型。
var b interface{}
b = 1
fmt.Printf("值:%v 类型:%Tn", b, b) //输出值:1 类型:int
(3)功能
a.空接口作为函数的参数
package main
import "fmt"
func show(a interface{}) {
fmt.Printf("值:%v 类型:%Tn", a, a)
}
func main() {
show(1)
show("abc")
show(true)
slice := []int{1, 2, 3}
show(slice)
}
b.map的值为空接口
var m1 = make(map[string]interface{})
m1["username"] = "张三"
m1["age"] = 20
m1["married"] = true
fmt.Printf("值:%#v 类型:%Tn", m1, m1)
b.slice的值为空接口
var s1 = []interface{}{"张三", 20, true, 32.2}
fmt.Printf("值:%#v 类型:%Tn", s1, s1) //值:[]interface {}{"张三", 20, true, 32.2} 类型:[]interface {}
5.类型断言
一个接口的值(简称接口值)是由一个具体类型和具体类型的值两部分组成的。这两部分分别称为接口的动态类型和动态值。 如果我们想要判断空接口中值的类型,那么这个时候就可以使用类型断言,其语法格式为:
x.(T)
其中:
- x:表示类型为interface()的变量。
- T:表示断言x可能是的类型。
该语法返回两个参数,第一个参数是 x 转化为 T 类型后的变量,第二个值是一个布尔值,若为 true 则表示断言成功,为 false 则表示断言失败。
例如:
package main
import "fmt"
func main() {
var a interface{} = 1
v, ok := a.(string)
if ok {
fmt.Println("a就是一个string类型", v)
} else {
fmt.Println("断言错误")
}
}
注意:类型.(type)只能结合 switch 语句使用
func justifyType(x interface{}) {
switch v := x.(type) {
case string:
fmt.Printf("x is a string,value is %vn", v)
case int:
fmt.Printf("x is a int is %vn", v)
case bool:
fmt.Printf("x is a bool is %vn", v)
default:
fmt.Println("unsupport type!")
}
}
暑期编程PK赛
得CSDN机械键盘等精美礼品!


