Go速成無壓力【七】:切片 (Slices)

(一)切片 (Slices)

一個數組有足夠的適合的長度,但是切片是從另一個方面來定義,是一個動態的尺寸,相當於一個靈活可擴展的數組;在實際操作練習中,切片比數組更常用

(1) 切片的類型表示用 [ ]T ,比如[ ] int , 則切片的類型爲int型;
(2) 一個切片由指定的兩個索引組成,一個低邊界的索引和一個高邊界的索引,使用分號分割開,寫法如:a[low:high];
(3) 切片索引選擇的範圍是半開型區間,包含索引的第一個元素,但是不包含第最後一個元素,比如,選擇4個元素a[1:5]
(4) 切片的索引是從0開始數數的

package main
import "fmt"
func main(){
	v := [5]int{1,3,5,7,9}
	fmt.Println("切片的值爲:",v)
	var s[]int = v[1:3]
	fmt.Println("切片1到3的範圍內的值爲:",s)
}

在這裏插入圖片描述



(二)切片就像對數組的引用

一個切片並不會存儲任何值,它僅僅是描述了一個底層的數組;改變切片的元素會相應地改變底層數組的元素,其他共享同樣的底層數組的切片也會知道這些改變

package main

import "fmt"

func main() {
	s := [4]string{
		"kok",
		"galarxy",
		"steven",
		"bot",
	}
	fmt.Println("打印的切片全部值爲:", s)

	r1 := s[0:1]
	r2 := s[2:4]
	fmt.Println("切片[0:1]和[2:4]的值分別爲:", r1, r2)
	r1[0] = "1024"
	fmt.Println("數組r1的值爲", r1)
	fmt.Println("在各種改變了底層數組的值後,切片的值爲:", s)
}

在這裏插入圖片描述



(三)切片的文法

一個切片的文法更像是一個沒有長度的數組

數組的文法

[3]bool{true,true,false}

切片的文法

[]bool{true,true,false}

實例演示

package main
import "fmt"
func main(){
	v1 := []int{2,3,4,5,5,11}
	fmt.Println("設定整型的v1的切片的值爲:",v)

	v2 := []bool{true,true,false}
	fmt.Println("設定bool類型的v2的切片的值爲",v2)

	v3 := []struct{
		x int
		y bool
	}{
		{2,false},
		{3,false},
		{4,true},
	}
	fmt.Println("設定結構體類型的v3的切片的值爲:",v3)

	v4 := []string{"Hello , golang !"}
	fmt.Println("設定字符串類型的v4的切片的值爲:",v4)
}

在這裏插入圖片描述



(四)切片的默認值

切片的默認值是指在切片不設置低邊界或者高邊界的時候,或者都不設置的時候,切片默認選擇的值

package main

import "fmt"

func main() {
	s := []int{2, 3, 4, 5, 6}
	s = s[1:3]
	fmt.Println("設置起始爲下標1,終止爲下標3", s)
	s = s[1:]
	fmt.Println("設置起始爲下標1,終止未設置", s)
	s = s[:3]
	fmt.Println("起始未設置,終止下標設置爲3", s)
	s = s[:]
	fmt.Println("不設置任何下標", s)
}

在這裏插入圖片描述



(五)切片的長度和容量

一個切片擁有長度和容量,切片的長度取決於切片本身包含包含的元素的數量,切片的容量是底層數組的元素數量,計數從切片的第一個元素開始

使用 len() 和 cap() 方法可以分別求得切片的長度和容量

package main

import "fmt"

func main() {
	s := []int{1, 2, 4, 7, 9}
	fmt.Printf("切片s的長度爲:%v \n", len(s))
	fmt.Printf("切片s的容量爲:%v \n", cap(s))
	s = s[:3]
	fmt.Printf("切片s[:3]的長度和容量分別爲:%v , %v", len(s), cap(s))
}

在這裏插入圖片描述



(六)空切片(Nil slices)

切片的值爲0時則變爲 nil
一個nil切片是一個0長度和0容量的切片,且沒有底層數組

package main
import "fmt"
func main(){
	var s []int
	fmt.Printf("%v , %v , %v",s , len(s) , cap(s))
	if s == nil {
		fmt.Println("切片s爲空,檢測值爲nil")
	}
}

在這裏插入圖片描述



(七)使用make()創建切片

使用內置函數make()可以創建一個具有動態尺寸的數組
make函數可以分配一個歸零的數組並且返回一個和數組相連的切片,語法爲:a := make([]int,長度,容量)

對於指定的容量,可以通過第三個參數去設置

package main

import "fmt"

func main() {
	mke1 := make([]int, 2, 5)
	fmt.Println("切片mke1的值,長度,容量分別爲:", mke1, len(mke1), cap(mke1))
	mke2 := make([]int, 0, 5)
	fmt.Println("切片mke2的值,長度,容量分別爲:", mke2, len(mke2), cap(mke2))
	mke3 := mke2[:3]
	fmt.Println("切片mke3的值,長度,容量分別爲:", mke3, len(mke3), cap(mke3))
}

在這裏插入圖片描述



(八)切片的切片

切片可以包含任何類型,可以包含任何切片

這是golang官網的一個演示實例

package main

import (
	"fmt"
	"strings"
)

func main() {
	// 創建一個井字棋
	board := [][]string{
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
	}

	// 玩家下完棋後的結果
	board[0][0] = "X"
	board[2][2] = "O"
	board[1][2] = "X"
	board[1][0] = "O"
	board[0][2] = "X"

	//循環輸出井字棋
	for i := 0; i < len(board); i++ {
		fmt.Printf("%s\n", strings.Join(board[i], " "))
	}
}

在這裏插入圖片描述



(九)添加到切片

添加一個新元素到切片,所以Go提供一個內置函數 append(),使用語法:func append(s []T , vs ...T)[]T
(1)第一個參數類型爲 T 的 s 是將被添加元素的數組,vs…T 是準備添加都切片 s 的值
(2)append() 函數會返回添加數據到原始切片後的結果
(3)如果返回的數組 s 太小卻被賦予太大的數據將會被再分配,返回的切片將會被指向較新分配的數組

package main

import "fmt"

func main() {
	var s []int
	s = append(s, 0)
	printSlice(s)
	s = append(s, 1, 2, 14)
	printSlice(s)
}

func printSlice(s []int) {
	fmt.Printf("切片%v的長度和容量分別爲:%v , %v \n", s, len(s), cap(s))
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章