Golang-Slice

155 阅读2分钟

slice与array的生成方式

slice可以从数组中生成,也可以直接创建,在创建的时候可以指定slice的长度和容量,如果没有指定容量(make的第三个参数),那么容量就默认和长度相同。也可以不通过make创建,而是直接通过var的方式声明一个零值的slice,则它的长度和容量都为0。

var s1 []byte = buffer[10:20]
var s2 []int
var s3 = make([]int, 10)
var s4 = make([]int, 10, 20)
s5 := []int{}
s2与s5的区别看下文:nil切片与空分片

Array 指定了长度生成的是数组,array是固定长度的数组,使用前必须确定数组长度

nums := [3]int{}

常用操作

github.com/golang/go/w…

Struct切片

初始化的方法

错误用法

package main

import "fmt"

type s struct {
	i int
}

func main() {
	ss := make([]s, 10)
	for _, si := range ss {
		si.i = 10
	}
	fmt.Printf("%+v", ss)
}

输出:

[{i:0} {i:0} {i:0} {i:0} {i:0} {i:0} {i:0} {i:0} {i:0} {i:0}]
Program exited.

正确初始化

通过append初始化

type MyStruct struct {
    F1, F2, F3, F4, F5, F6, F7 string
    I1, I2, I3, I4, I5, I6, I7 int64
}

func BenchmarkAppendingStructs(b *testing.B) {
    var s []MyStruct

    for i := 0; i < b.N; i++ {
        s = append(s, MyStruct{})
    }
}

func BenchmarkAppendingPointers(b *testing.B) {
    var s []*MyStruct

    for i := 0; i < b.N; i++ {
        s = append(s, &MyStruct{})
    }
}

直接使用下表地址初始化

package main

import "fmt"

type s struct {
	i int
}

func main() {
	ss := make([]s, 10)
	for idx := range ss {
		ss[idx].i = idx
	}
	fmt.Printf("%+v", ss)
}

输出:

[{i:0} {i:1} {i:2} {i:3} {i:4} {i:5} {i:6} {i:7} {i:8} {i:9}]
Program exited.

通过指针初始化

package main

import "fmt"

type s struct {
	i int
}

func main() {
	ss := make([]s, 10)
	for idx := range ss {
		si := &ss[idx]
		si.i = idx
	}
	fmt.Printf("%+v", ss)
}

输出:

[{i:0} {i:1} {i:2} {i:3} {i:4} {i:5} {i:6} {i:7} {i:8} {i:9}]
Program exited.

Sturct指针数组初始化

package main

import "fmt"

type s struct {
	i int
}

func main() {
	ss := make([]*s, 10)
	for idx := range ss {
		//需要初始化
		ss[idx] = &s{}
		ss[idx].i = idx
	}
	fmt.Printf("%+v\n", ss)
	fmt.Printf("%+v", ss[9])

}

输出:

[0xc00018c000 0xc00018c008 0xc00018c010 0xc00018c018 0xc00018c020 0xc00018c028 0xc00018c030 0xc00018c038 0xc00018c040 0xc00018c048]
&{i:9}
Program exited.

Golang 结构体切片,大家的习惯是切片元素是结构体值还是指针

一律优先用指针,遇到特殊情况才直接用结构体。

另外在 Go 里,给一个结构体添加方法,官方也是提倡优先对其指针添加方法,像这样 func (foobar *Foobar) Method(){}

map中的value如果要用结构体,也建议用指针。因为如果 value 是一个结构体,可以直接替换结构体,但无法更新结构体内部的值。 webcache.googleusercontent.com/search?q=ca…

nil切片与空分片

package main

import "fmt"

func main() {
	var s1 []int
	var s2 = []int{}

	fmt.Println(s1 == nil)
	fmt.Println(s2 == nil)

	fmt.Printf("%#v\n", s1)
	fmt.Printf("%#v\n", s2)
}

-------
true
false
[]int(nil)
[]int{}

juejin.cn/post/684490…