一.指针
类型 *T
是指向 T
类型值的指针。其零值为 nil
。
&
操作符会生成一个指向其操作数的指针。
*
操作符表示指针指向的底层值(变量值)。
//指针-例
package main
import "fmt"
func main() {
i, j := 42, 2701
p := &i // 指向 i
fmt.Println(p) // 读取指针 的值 输出:0x414020
fmt.Println(*p) // 通过指针读取 i 的值 输出:42
*p = 21 // 通过指针设置 i 的值 输出:21
fmt.Println(i) // 查看 i 的值
p = &j // 指向 j
*p = *p / 37 // 通过指针对 j 进行除法运算
fmt.Println(j) // 查看 j 的值 输出:73
}
二.结构体:一个结构体(struct
)就是一组字段(field)。可以看做是key_value键值对.
2.1 结构体字段
//结构体
//例一
package main
import "fmt"
type Vertex struct {
X int
Y int
}
func main() {
fmt.Println(Vertex{1, 2})
}
//输出
{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) //输出4
fmt.Println(v) //输出{4 2}
}
2.2 结构体指针
如果我们有一个指向结构体的指针 p
,那么可以通过 (*p).X
来访问其字段 X
。不过这么写太啰嗦了,所以语言也允许我们使用隐式间接引用,直接写 p.X
就可以。即 (*p).X
等同于p.x.
package main
import "fmt"
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
p := &v
p.X = 100
fmt.Println(v) //输出{100 2}
(*p).X = 200
fmt.Println(v) //输出{200 2}
}
使用 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: 1,Y: 9} // Y:0 被隐式地赋予
v4 = Vertex{} // X:0 Y:0
p = &Vertex{1, 2} // 创建一个 *Vertex 类型的结构体(指针)
)
func main() {
fmt.Println(v1, v2, v3, v4, p)
}
//输出
{1 2} {1 0} {1 9} {0 0} &{1 2}
三. 数组
3.1 定义
var a [10]int 表示: 类型 [n]T表示拥有 n个 T类型的值的数组。数组的长度是其类型的一部分,因此数组不能改变大小.
package main
import "fmt"
func main() {
var a [2]string
a[0] = "Hello"
a[1] = "World"
fmt.Println(a[0], a[1]) //输出Hello World
fmt.Println(a) //输出[Hello World]
primes := [6]int{2, 3, 5, 7, 11, 13}
fmt.Println(primes) //输出[2 3 5 7 11 15]
primes = [6]int{2, 3}
fmt.Println(primes) //输出[2 3 0 0 0 0]
}
3.2 切片
每个数组的大小都是固定的。而切片则为数组元素提供动态大小的、灵活的视角。在实践中,切片比数组更常用。
类型 []T
表示一个元素类型为 T
的切片。
切片通过两个下标来界定,即一个上界和一个下界,二者以冒号分隔:
a[low : high]
它会选择一个半开区间,包括第一个元素,但排除最后一个元素。
以下表达式创建了一个切片,它包含 a
中下标从 1 到 3 的元素:
a[1:4]
package main
import "fmt"
func main() {
primes := [6]int{2, 3, 5, 7, 11, 13}
var s []int = primes[1:4]
fmt.Println(s) //输出[3 5 7]
}
切片值传递方式为引用传递
//例一
package main
import "fmt"
func main() {
names := [4]string{
"John",
"Paul",
"George",
"Ringo",
}
fmt.Println(names) //输出[John Paul George Ringo]
a := names[0:2]
b := names[1:3]
fmt.Println(a, b) //输出[John Paul] [Paul George]
b[0] = "XXX"
fmt.Println(a, b) //输出[John XXX] [XXX George]
fmt.Println(names) //输出[John XXX George Ringo]
}
//例二
package main
import "fmt"
func main() {
q := []int{2, 3, 5, 7, 11, 13}
fmt.Println(q) //输出[2 3 5 7 11 13]
r := []bool{true, false, true, true, false, true}
fmt.Println(r) //输出[true false true true false true]
s := []struct {
i int
b bool
}{
{2, true},
{3, false},
{5, true},
{7, true},
{11, false},
{13, true},
}
fmt.Println(s) //输出[{2 true} {3 false} {5 true} {7 true} {11 false} {13 true}]
}
切片的默认行为
在进行切片时,你可以利用它的默认行为来忽略上下界。
切片下界的默认值为 0
,上界则是该切片的长度。
对于数组
var a [10]int
来说,以下切片是等价的:
a[0:10] a[:10] a[0:] a[:]
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
s = s[1:4]
fmt.Println(s) //输出[3 5 7]
s = s[:2]
fmt.Println(s) //输出[3 5]
s = s[1:]
fmt.Println(s) //输出[5]
var a [10]int
fmt.Println(a) //输出[0 0 0 0 0 0 0 0 0 0]
}