指针
Go 具有指针。 指针保存了变量的内存地址。
类型 *T
是指向类型 T
的值的指针。其零值是 `nil`。
var p *int
&
符号会生成一个指向其作用对象的指针。
i := 42
p = &i
*
符号表示指针指向的底层的值。
fmt.Println(*p) // 通过指针 p 读取 i
*p = 21 // 通过指针 p 设置 i
这也就是通常所说的“间接引用”或“非直接引用”。
与 C 不同,Go 没有指针运算。
例子:
package main
import "fmt"
func main() {
i, j := 42, 2701
p := &i // point to i
fmt.Println(*p) // read i through the pointer
*p = 21 // set i through the pointer
fmt.Println(i) // see the new value of i
p = &j // point to j
*p = *p / 37 // divide j through the pointer
fmt.Println(j) // see the new value of j
}
结构体
一个结构体(`struct`)就是一个字段的集合。可用于表示不同数据类型的集合。
结构体是由零个或多个任意类型的值聚合成的实体。
(而 type
的含义跟其字面意思相符。)
package main
import "fmt"
type Vertex struct {
X int
Y int
}
func main() {
fmt.Println(Vertex{1, 2})
}
结构体字段使用点号来访问。
package main
import "fmt"
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v.X)
}
结构体字段也可以通过结构体指针来访问。
ps:官方对此提到一句“通过指针间接的访问是透明的”,对此句中的“透明的”暂不知该如何解释,网上暂时也没找到解释。我最初误会以为可以通过指针访问私有变量,但经过尝试,事实并不可以。
结构体文法
结构体文法表示通过结构体字段的值作为列表来新分配一个结构体。
使用 Name:
语法可以仅列出部分字段。(字段名的顺序无关。)
特殊的前缀 &
返回一个指向结构体的指针。
package main
import "fmt"
type Vertex struct {
X, Y int
}
var (
v1 = Vertex{1, 2} // 类型为 Vertex
v2 = Vertex{X: 1} // Y:0 被省略
v3 = Vertex{} // X:0 和 Y:0
p = &Vertex{1, 2} // 类型为 *Vertex
)
func main() {
fmt.Println(v1, p, v2, v3)
}
输出结果:
结构体内嵌匿名成员
声明一个成员对应的数据类型而不指名成员的名字;这类成员就叫匿名成员。
package main
import "fmt"
type Person struct {
Age int
Name string
}
type Student struct {
Person
}
func main() {
per := Person{
Age: 18,
Name: "name",
}
stu := Student{Person: per}
fmt.Println("stu.Age: ", stu.Age)
fmt.Println("stu.Name: ", stu.Name)
}
Go的面向对象中通常用匿名成员实现继承。
数组
- 定义:由若干相同类型的元素组成的序列
- 数组的长度是固定的,声明后无法改变
- 数组的长度是数组类型的一部分,eg:元素类型相同但是长度不同的两个数组是不同类型的
- 需要严格控制程序所使用内存时,数组十分有用,因为其长度固定,避免了内存二次分配操作
类型 [n]T
是一个有 n
个类型为 T
的值的数组。
表达式
var a [10]int
定义变量