Yayako's Blog

「Shooting for the stars when I couldn't make a killing.」

仅作java2go的简单记录,有错误烦请提出

合集整理:Java转Go的学习-合集

demo已上传git:https://gitee.com/yayako/go-learning.git

接口和类型断言

接口的简单使用

结构定义

1
2
3
type 接口名 interface {
// 接口内容
}

现定义一个usb接口、Phone结构体如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
type Phone struct {
Name string
}

type Usber interface {
charge()
transport()
InnerInterface // 内嵌接口
}

type InnerInterface interface {
fix()
}

接口必须实现接口必须实现接口内的所有方法

1
2
3
4
5
6
7
8
9
10
11
func (p *Phone) transport() {
fmt.Println(p.Name, "修理")
}

func (p *Phone) charge() {
fmt.Println(p.Name, "充电")
}

func (p *Phone) fix() {
fmt.Println(p.Name, "修理")
}

实现所有方法之后就可以使用

image-20210206193804517

创建接口实例的两种方式

  • var u = Usber(&Phone{Name: "OPPO"})
    
    1
    2
    3

    - ```go
    var u Usber = &Camera{Name: "Casio"}
    ![image-20210206194228198](https://typora-yayako.oss-cn-hangzhou.aliyuncs.com/image-20210206194228198.png)

值类型接收者和指针类型接收者实现接口

写法的区别仅在于接口实现方法的接收者是值类型还是指针类型

值类型接收者

值类型实例 和 指针类型实例 都可以赋值给 值类型接收者 的接口变量——如果结构体中的方法是值接收者(Camera实现的方法),那么实例化后的结构体值类型和结构体指针类型都可以赋值给接口变量(u2和u3)。

1
2
3
4
5
6
7
8
func (c Camera) charge() {
fmt.Println(c.Name, "充电")
}

func main() {
var u2 Usber = Camera{Name: "Casio"}
var u3 Usber = &Camera{Name: "Sony"}
}
指针类型接收者

只能将实例化后的 结构体指针类型 赋值给 指针类型接收者 的接口变量——如果结构体中的方法是指针接收者,那么实例化后结构体指针类型可以赋值给接口变量,结构体值类型无法赋值。

1
2
3
4
5
6
7
func (p *Phone) charge() {
fmt.Println(p.Name, "充电")
}

func main() {
var u1 Usber = &Phone{Name: "VIVO"}
}

空接口

没有任何约束的接口,任何类型变量都可以实现空接口,是go中类似Java中Object的存在。

1
type Object interface{}

以该方法为例

1
2
3
func show(o interface{}) {
fmt.Printf("值:%v,类型:%T\n", o, o) // 1 int
}

依次调用

1
2
3
4
show(1)    // 值:1,类型:int
show("1") // 值:1,类型:string
show(1.1) // 值:1.1,类型:float64
show(true) // 值:true,类型:bool

同理可用于map、slice等结构

1
2
3
4
5
userinfo := make(map[string]interface{})
userinfo["name"] = "张三"
userinfo["age"] = 22
userinfo["hobby"] = []string{"吃饭", "睡觉", "打豆豆"}
userinfo["phone"] = Phone{Name: "oppo"}

但是空接口类型不支持索引、自定义类型,不过可以通过类型断言转换

类型断言

用于判断空接口中值的类型

格式如下,返回转换后的变量和布尔值

1
x.(T) // 源数据.(目标类型)

举个简单的例子

1
2
3
4
5
6
7
8
9
var b interface{}
b = "你好,golang"
v, ok := b.(string)
if ok {
fmt.Println("a是一个string类型的值 ——", v)
} else {
fmt.Println("a不是一个string类型的值")
}
// a是一个string类型的值 —— 你好,golang

再以上面的map为例

1
2
3
4
// 	fmt.Println(userinfo["hobby"][1]) 	✖	type interface {} does not support indexing
// fmt.Println(userinfo["phone"].Name) ✖ type interface {} is interface with no methods
fmt.Println(userinfo["hobby"].([]string)[0])
fmt.Println(userinfo["phone"].(Phone).Name)

评论