Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

My Blog

从此烟雨落金城,一人撑伞两人行。

第8章:对象

匿名字段

提供类型而不写字段名的方式,也就是匿名字段,也称为嵌入字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import "fmt"

//go支持只提供类型而不写字段名的方式,也就是匿名字段,也称为嵌入字段
type Person struct {
name string
sex string
age int
}

type Student struct {
Person
id int
addr string
}

func main() {
// 初始化
s1 := Student{Person{"5lmh", "man", 20}, 1, "bj"}
fmt.Println(s1)

s2 := Student{Person: Person{"5lmh", "man", 20}}
fmt.Println(s2)

s3 := Student{Person: Person{name: "5lmh"}}
fmt.Println(s3)
}

所有的内置类型和自定义类型都是可以作为匿名字段去使用

接口

接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节。

在Go语言中接口(interface)是一种类型,一种抽象的类型。

接口定义

1
2
3
4
5
6
接口是一个或多个方法签名的集合。
任何类型的方法集中只要拥有该接口'对应的全部方法'签名。
就表示它 "实现" 了该接口,无须在该类型上显式声明实现了哪个接口。
接口可以匿名嵌入其他接口,或嵌入到结构中。
只有当接口存储的类型和对象都为nil时,接口才等于nil。
空接口可以作为任何类型数据的容器。
1
2
3
4
5
type 接口类型名 interface{
方法名1( 参数列表1 ) 返回值列表1
方法名2( 参数列表2 ) 返回值列表2

}

一个对象只要全部实现了接口中的方法,那么就实现了这个接口。

接口类型变量能够存储所有实现了该接口的实例。

使用值接收者实现接口之后,不管是dog结构体还是结构体指针*dog类型的变量都可以赋值给该接口变量。因为Go语言中有对指针类型变量求值的语法糖.

指针接收者实现接口

1
2
3
4
5
6
7
8
9
10
func (d *dog) move() {
fmt.Println("狗会动")
}
func main() {
var x Mover
var wangcai = dog{} // 旺财是dog类型
x = wangcai // x不可以接收dog类型
var fugui = &dog{} // 富贵是*dog类型
x = fugui // x可以接收*dog类型
}

此时实现Mover接口的是*dog类型,所以不能给x传入dog类型的wangcai,此时x只能存储*dog类型的值。

一个类型可以同时实现多个接口,而接口间彼此独立,不知道对方的实现。

Go语言中不同的类型还可以实现同一接口.

一个接口的方法,不一定需要由一个类型完全实现,接口的方法可以通过在类型中嵌入其他类型或者结构体来实现。

接口与接口间可以通过嵌套创造出新的接口。

空接口

空接口是指没有定义任何方法的接口。因此任何类型都实现了空接口。

空接口类型的变量可以存储任意类型的变量。

  • 空接口作为函数的参数

  • 空接口作为map的值

类型断言

一个接口的值(简称接口值)是由一个具体类型和具体类型的值两部分组成的。这两部分分别称为接口的动态类型和动态值。

判断空接口中的值这个时候就可以使用类型断言,其语法格式:

1
2
3
 x.(T) 
x:表示类型为interface{}的变量
T:表示断言x可能是的类型。

返回两个参数,第一个参数是x转化为T类型后的变量,第二个值是一个布尔值,若为true则表示断言成功,为false则表示断言失败。

评论