GO语言基础(三) | 青训营笔记

189 阅读4分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第4篇笔记。

基础知识(三)

结构体

结构体文法通过直接列出字段的值来新分配一个结构体。

Go 没有构造函数!

几种声明格式:

var entity StructName{}
var entity StructName//编译器会初始化好
var entity *StructName //初始化为nil


entity := new(StructName)
entity := StructName{}
entity := &StructName{}
entity := StructName{Field1:value1,Field2:value2}


结构体指针自引用时只能使用指针,因为此时才可确认初始化的地址空间的大小。

结构体是如何实现接口的?《鸭子类型》

一个结构体只要实现了接口中的所有方法就实现了该接口

并且不需要引用对应的包就能实现跨包接口

type

  • type name interface{ }

  • type name struct{ }

  • type name 别的类型

  • type 别名 = 别的类型

方法

Go 没有类。不过你可以为结构体类型定义方法。

方法就是一类带特殊的 接收者 参数的函数。

方法接收者在它自己的参数列表内,位于 func 关键字和方法名之间。

type Vertex struct {
	X, Y float64
}
func (v Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
	v := Vertex{3, 4}
	fmt.Println(v.Abs())
}

方法就是函数 ,。方法只是个带接收者参数的函数。

只能为在同一包内定义的类型的接收者声明方法,而不能为其它包内定义的类型(包括 int 之类的内建类型)的接收者声明方法

接收者的类型定义和方法声明必须在同一包内;不能为内建类型声明方法

可以为指针接收者声明方法指针接收者的方法可以修改接收者指向的值

带指针参数的函数必须接受一个指针:而以指针为接收者的方法被调用时,接收者既能为值又能为指针Go 会将语句 v.Scale(5) 解释为 (&v).Scale(5)以值为接收者的方法被调用时,接收者既能为值又能为指针:会把指针转成值

使用指针接收者的原因有二:

首先,方法能够修改其接收者指向的值。

其次,这样可以避免在每次调用方法时复制该值。若值的类型为大型结构体时,这样做会更加高效。

方法声明与调用中:

1、支持多返回值;

2、方法的作用域与变量的作用域一样,通过大小写进行控制。

3、可以对返回值进行命名;

接口

**接口类型是由一组方法签名定义的集合。**接口类型的变量可以保存任何实现了这些方法的值。

由于 方法只为指针类型定义,因此值类型并未实现 接口。

接口的隐式实现:类型通过实现一个接口的所有方法来实现该接口。既然无需专门显式声明,也就没有“implements”关键字。

隐式接口从接口的实现中解耦了定义,这样接口的实现可以出现在任何包中,无需提前准备。

因此,也就无需在每一个实现上增加新的接口名称,这样同时也鼓励了明确的接口定义。

接口也是值。它们可以像其它值一样传递。

接口值可以用作函数的参数或返回值。

在内部,接口值可以看做包含值和具体类型的元组:

接口值保存了一个具体底层类型的具体值。接口值调用方法时会执行其底层类型的同名方法

即便接口内的具体值为 nil,方法仍然会被 nil 接收者调用。???注意: 保存了 nil 具体值的接口其自身并不为 nil。

nil 接口值既不保存值也不保存具体类型。

为 nil 接口调用方法会产生运行时错误,因为接口的元组内并未包含能够指明该调用哪个 具体 方法的类型。

类型断言 提供了访问接口值底层具体值的方式。t, ok := i.(T)

类型选择 是一种按顺序从几个类型断言中选择分支的结构。

类型选择与一般的 switch 语句相似,不过类型选择中的 case 为类型(而非值), 它们针对给定接口值所存储的值的类型进行比较。

switch v := i.(type) {
case T:
    // v 的类型为 T
case S:
    // v 的类型为 S
default:
    // 没有匹配,v 与 i 的类型相同
}

类型选择中的声明与类型断言 i.(T) 的语法相同,只是具体类型 T 被替换成了关键字 type

此选择语句判断接口值 i 保存的值类型是 T 还是 S。在 TS 的情况下,变量 v 会分别按 TS 类型保存 i 拥有的值。在默认(即没有匹配)的情况下,变量 vi 的接口类型和值相同。