标签:iba 实现类 == 支持 具体类 mac 失败 的区别 ash
package main
import "fmt"
type Cat struct{}
func (c Cat) Say() string {return "miao miao miao"}
type Dog struct{}
func (d Dog) Say() string {return "wang wang wang"}
func main() {
c := Cat{}
fmt.Println(c)
fmt.Println(c.Say())
d := Dog{}
fmt.Println(d)
fmt.Println(d.Say())
}
{}
miao miao miao
{}
wang wang wang
接口是一个或多个方法签名的集合。
任何类型的方法集中只要拥有该接口‘对应的全部方法‘签名。
就表示它 "实现" 了该接口,无须在该类型上显式声明实现了哪个接口。
这称为Structural Typing。
所谓对应方法,是指有相同名称、参数列表 (不包括参数名) 以及返回值。
当然,该类型还可以有其他方法。
接口只有方法声明,没有实现,没有数据字段。
接口可以匿名嵌入其他接口,或嵌入到结构中。
对象赋值给接口时,会发生拷贝,而接口内部存储的是指向这个复制品的指针,既无法修改复制品的状态,也无法获取指针。
只有当接口存储的类型和对象都为nil时,接口才等于nil。
接口调用不会做receiver的自动转换。
接口同样支持匿名字段方法。
接口也可实现类似OOP中的多态。
空接口可以作为任何类型数据的容器。
一个类型可实现多个接口。
接口命名习惯以 er 结尾。
type 接口类型名 interface{
方法名1( 参数列表1 ) 返回值列表1
方法名2( 参数列表2 ) 返回值列表2
…
}
1.接口名:使用type将接口定义为自定义的类型名。Go语言的接口在命名时,一般会在单词后面添加er,如有写操作的接口叫Writer,有字符串功能的接口叫Stringer等。接口名最好要能突出该接口的类型含义。
2.方法名:当方法名首字母是大写且这个接口类型名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码访问。
3.参数列表、返回值列表:参数列表和返回值列表中的参数变量名可以省略。
package main
import "fmt"
type Sayer interface {
say()
}
type dog struct {}
type cat struct {}
func (d dog) say() {
fmt.Println("wang wang wang")
}
func (c cat) say() {
fmt.Println("miao miao miao")
}
func main() {
d:=dog{}
d.say()
c:=cat{}
c.say()
}
wang wang wang
miao miao miao
package main
import "fmt"
type Sayer interface {
say()
}
type dog struct {}
type cat struct {}
func (d dog) say() {
fmt.Println("wang wang wang")
}
func (c cat) say() {
fmt.Println("miao miao miao")
}
func main() {
var x Sayer
d:=dog{}
c:=cat{}
x = d
x.say()
x = c
x.say()
}
wang wang wang
miao miao miao
package main
import "fmt"
type dog struct {}
type Mover interface {
move()
}
func (d dog) move() {
fmt.Println("狗会动了")
}
func main() {
var x Mover
var wangci = dog{}//wangci是dog类型
x = wangci//用x接受dog类型
var fugui = &dog{}//fugui是*dog类型
x = fugui// x可以接收*dog类型
x.move()
}
*dog
类型的变量都可以赋值给该接口变量。因为Go语言中有对指针类型变量求值的语法糖,dog指针fugui内部会自动求值*fugui
。package main
import "fmt"
type People interface {
Speak(string) string
}
type Student struct {}
func (stu *Student) Speak(think string) (talk string) {
if think == "sb"{
talk = "帅小哥一枚"
} else {
talk = "你好"
}
return
}
func main() {
var peo People = Student{}
think := "bitch"
fmt.Println(peo.Speak(think))
}
package main
import "fmt"
type Sayer interface {
say()
}
type Mover interface {
move()
}
type dog struct {
name string
}
func (d dog) say() {
fmt.Printf("%s 会叫汪汪汪\n", d.name)
}
func (d dog) move() {
fmt.Printf("%s 会动啊\n", d.name)
}
func main() {
var x Sayer
var y Mover
var a = dog{name: "旺财"}
x = a
y = a
x.say()
y.move()
}
旺财 会叫汪汪汪
旺财 会动啊
package main
import "fmt"
type Mover interface {
move()
}
type dog struct {
name string
}
type car struct {
brand string
}
func (d dog) move() {
fmt.Printf("%s会跑\n", d.name)
}
func (c car) move() {
fmt.Printf("%s 速度是70迈\n", c.brand)
}
func main() {
var x Mover
var a = dog{name:"wangcai"}
var b = car{brand: "benteng"}
x = a
x.move()
x = b
x.move()
}
wangcai会跑
benteng 速度是70迈
package main
import "fmt"
type Mover interface {
move()
}
type dog struct {
name string
}
type car struct {
brand string
}
func (d dog) move() {
fmt.Printf("%s会跑\n", d.name)
}
func (c car) move() {
fmt.Printf("%s 速度是70迈\n", c.brand)
}
type WashingMachine interface {
wash()
dry()
}
type dryer struct {}
func (d dryer) dry() {
fmt.Println("甩一下")
}
type haier struct {
dryer
}
func (h haier) wash() {
fmt.Println("洗刷帅")
}
func main() {
var x Mover
var a = dog{name:"wangcai"}
var b = car{brand: "benteng"}
x = a
x.move()
x = b
x.move()
}
package main
import "fmt"
type WashingMachine interface {
wash()
dry()
}
type dryer struct {}
func (d dryer) dry() {
fmt.Println("甩一下")
}
type haier struct {
dryer
}
func (h haier) wash() {
fmt.Println("洗刷帅")
}
func main() {
var x WashingMachine
var hai = haier{}
x = hai
x.wash()
x.dry()
}
洗刷帅
甩一下
接口与接口间可以通过潜逃创造出新的接口
package main
import "fmt"
type Sayer interface {
say()
}
type Mover interface {
move()
}
type animal interface {
Sayer
Mover
}
type cat struct {
name string
}
func (c cat) say() {
fmt.Println("miao miao miao", c.name)
}
func (c cat) move() {
fmt.Println("mao is move")
}
func main() {
var x animal
x = cat{name:"huahua"}
x.move()
x.say()
}
package main
import "fmt"
func main() {
var x interface{}
s := "ppro.cn"
x = s
fmt.Printf("type:%T value:%v\n", x, x)
i := 100
x = i
fmt.Printf("type:%T, value:%v\n",x,x)
b := true
x = b
fmt.Printf("type:%T, value:%v\n",x,x)
}
type:string value:ppro.cn
type:int, value:100
type:bool, value:true
func show(a interface{}){
fmt.Printf("type:%T value:%v\n",a,a)
}
func main() {
var studentInfo = make(map[string]interface{})
studentInfo["name"] = "libai"
studentInfo["age"] = 18
studentInfo["married"] = false
fmt.Println(studentInfo)
}
map[age:18 married:false name:libai]
// 键是string,值是interface
空接口可以存储任意类型的值,那我们如何获取存储的具体数据?
接口值:
一个接口的值(简称接口值) 是由一个具体类型和具体类型的值两部分组成的,这两部分分别称为接口的动态类型动态值。
如果想要判断空接口中值可以使用类型断言,语法是:
x.(T)
其中:
x: 表示类型为interface{}的变量
T:表示断言x可能是的类型
该语法返回两个参数,第一个参数是x转化为T类型后的变量,第二个值是一个布尔值,若为true则表示断言成功,为false则表示断言失败。
package main
import (
"fmt"
)
func main() {
var x interface{}
v, ok := x.(string)
if ok {
fmt.Println(v)
} else {
fmt.Println("类型断言失败")
}
}
Switch...case语句
func justifyType(x interface{}){
switch v := x.(type) {
case string:
fmt.Printf("x is string,value is %v\n", v)
case int:
fmt.Printf("x is a int is %v\n",v)
case bool:
fmt.Printf("x is bool is %v\n",v)
default:
fmt.Printf("unsupport type!")
}
}
因为空接口可以存储任意类型值的特点,所以空接口在Go语言中的使用十分广泛。
关于接口需要注意的是,只有当有两个或两个以上的具体类型必须以相同的方式进行处理时才需要定义接口。不要为了接口而写接口,那样只会增加不必要的抽象,导致不必要的运行时损耗。
标签:iba 实现类 == 支持 具体类 mac 失败 的区别 ash
原文地址:https://www.cnblogs.com/xujunkai/p/13341636.html