值接收者和指针接收者
使用值接收者实现接口与使用指针接收者实现接口的区别?
使用值接收者实现接口:结构体类型和结构体指针类型的变量都能存
使用指针接收者实现接口:只能存结构体指针类型的变量
package main
import "fmt"
// 使用值接收者和指针接收者的区别
type animal interface {
move()
eat(string)
}
type cat struct {
name string
feet int8
}
// // 使用值接收者实现了接口的所有方法
// func (c cat) move() {
// fmt.Println("走猫步...")
// }
// func (c cat) eat(food string) {
// fmt.Printf("猫吃%s...\n", food)
// }
// 使用指针接收者实现了接口的所有方法
func (c *cat) move() {
fmt.Println("走猫步...")
}
func (c *cat) eat(food string) {
fmt.Printf("猫吃%s...\n", food)
}
func main() {
var a1 animal
c1 := cat{"tom", 4} // cat
c2 := &cat{"假老练", 4} // *cat
// a1 = c1
a1 = &c1 // 实现animal这个接口的是cat的指针类型
fmt.Println(a1) // {tom 4} &{tom 4}
a1 = c2
fmt.Println(a1) // &{假老练 4}
}
接口和类型的关系
多个类型可以实现同一个接口
一个类型可以实现多个接口
package main
import "fmt"
// 同一个结构体可以实现多个接口
// 接口还可以嵌套
type animal interface {
mover
eater
}
type mover interface {
move()
}
type eater interface {
eat(string)
}
type cat struct {
name string
feet int8
}
// cat实现了moveer接口
func (c *cat) move() {
fmt.Println("走猫步...")
}
// cat实现了eater接口
func (c *cat) eat(food string) {
fmt.Printf("猫吃%s...\n", food)
}
func main() {
}
空接口
没有必要起名字,通常定义成下面的格式:
interface {} // 空接口
所有的类型都实现了空接口,也就是任意类型的变量都能保存到空接口中
package main
import "fmt"
// 空接口
// interface: 关键字
// interface(): 空接口类型
// 空接口作为函数参数
func show(a interface{}) {
fmt.Printf("type:%T value:%v\n", a, a)
}
func main() {
var m1 map[string]interface{}
m1 = make(map[string]interface{}, 16)
m1["name"] = "李霞"
m1["age"] = 18
m1["merried"] = true
m1["hobby"] = [...]string{"唱", "跳", "rap"}
fmt.Println(m1)
show(false)
show(nil)
show(m1)
}
从接口值中获取到对应的实际值需要使用类型断言,其语法格式如下。
x.(T)
其中:
- x:表示接口类型的变量
- T:表示断言x可能是的类型。
该语法返回两个参数,第一个参数是x转化为T类型后的变量,第二个值是一个布尔值,若为true则表示断言成功,为false则表示断言失败。
我想指定空接口接收的值具体是什么?
接口是一种类型,一种抽象的类型,它是一个只要求实现特定方法的抽象类型
package main
import (
"fmt"
)
// 类型断言1
func assign(a interface{}) {
fmt.Printf("%T\n", a)
str, ok := a.(string)
if !ok {
fmt.Println("猜错了")
} else {
fmt.Println("传进来的是一个字符串:", str)
}
}
// 类型断言2
func assign2(a interface{}) {
fmt.Printf("%T\n", a)
switch t := a.(type) {
case string:
fmt.Println("是一个字符串:", t)
case int:
fmt.Println("是一个int:", t)
case int64:
fmt.Println("是一个int64:", t)
case bool:
fmt.Println("是一个bool:", t)
}
}
func main() {
assign(100)
assign2(true)
assign2("学海无涯苦作舟")
assign2(int64(200))
}