最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

golang中的空slice案例

 更新時間:2021年04月26日 14:55:10   作者:晨夢思雨  
這篇文章主要介紹了golang中的空slice案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

golang中允許對值為 nil 的 slice 添加元素

package main 
func main() {
 var s []int
 s = append(s, 1)
}

運行成功~

補充:golang slice 詳解

一、數(shù)組切片的使用

func main() {
	//1.基于數(shù)組創(chuàng)建數(shù)組切片
	var array [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	var slice = array[1:7] //array[startIndex:endIndex] 不包含endIndex
	//2.直接創(chuàng)建數(shù)組切片
	slice2 := make([]int, 5, 10)
	//3.直接創(chuàng)建并初始化數(shù)組切片
	slice3 := []int{1, 2, 3, 4, 5, 6}
	//4.基于數(shù)組切片創(chuàng)建數(shù)組切片
	slice5 := slice3[:4]
	//5.遍歷數(shù)組切片
	for i, v := range slice3 {
		fmt.Println(i, v)
	}
	//6.len()和cap()
	var len = len(slice2) //數(shù)組切片的長度
	var cap = cap(slice)  //數(shù)組切片的容量
	fmt.Println("len(slice2) =", len)
	fmt.Println("cap(slice) =", cap)
	//7.append() 會生成新的數(shù)組切片
	slice4 := append(slice2, 6, 7, 8)
	slice4 = append(slice4, slice3...)
	fmt.Println(slice4)
	//8.copy() 如果進行操作的兩個數(shù)組切片元素個數(shù)不一致,將會按照個數(shù)較小的數(shù)組切片進行復制
	copy(slice2, slice3) //將slice3的前五個元素復制給slice2
	fmt.Println(slice2, slice3)
}

二、數(shù)組切片數(shù)據(jù)結(jié)構(gòu)分析

數(shù)組切片slice的數(shù)據(jù)結(jié)構(gòu)如下,一個指向真實array地址的指針ptr,slice的長度len和容量cap

// slice 數(shù)據(jù)結(jié)構(gòu)
type slice struct {
	array unsafe.Pointer 
	len   int            
	cap   int            
}

當傳參時,函數(shù)接收到的參數(shù)是數(shù)組切片的一個復制,雖然兩個是不同的變量,但是它們都有一個指向同一個地址空間的array指針,當修改一個數(shù)組切片時,另外一個也會改變,所以數(shù)組切片看起來是引用傳遞,其實是值傳遞。

三、append()方法解析

3.1 數(shù)組切片不擴容的情況

運行以下代碼思考一個問題:s1和s2是指向同一個底層數(shù)組嗎?

func main() {
	array := [20]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
	s1 := array[:5]
	s2 := append(s1, 10)
	fmt.Println("s1 =", s1)
	fmt.Println("s2 =", s2)
	s2[0] = 0
	fmt.Println("s1 =", s1)
	fmt.Println("s2 =", s2)
}

輸出結(jié)果:

s1 = [1 2 3 4 5]

s2 = [1 2 3 4 5 10]

s1 = [0 2 3 4 5]

s2 = [0 2 3 4 5 10]

由第一行和第二行結(jié)果看來,似乎這是指向兩個不同的數(shù)組;但是當修改了s2,發(fā)現(xiàn)s1也跟著改變了,這又表明二者是指向同一個數(shù)組。到底真相是怎樣的呢?

運行以下代碼:

import (
	"fmt"
	"unsafe"
)
type Slice struct {
	ptr unsafe.Pointer // Array pointer
	len int            // slice length
	cap int            // slice capacity
}
func main() {
	array := [20]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
	s1 := array[:5]
	s2 := append(s1, 10)
	s2[0] = 0
	// 把slice轉(zhuǎn)換成自定義的 Slice struct
	slice1 := (*Slice)(unsafe.Pointer(&s1))
	fmt.Printf("ptr:%v len:%v cap:%v \n", slice1.ptr, slice1.len, slice1.cap)
	slice2 := (*Slice)(unsafe.Pointer(&s2))
	fmt.Printf("ptr:%v len:%v cap:%v \n", slice2.ptr, slice2.len, slice2.cap)
}

輸出結(jié)果:

ptr:0xc04205e0a0 len:5 cap:20

ptr:0xc04205e0a0 len:6 cap:20

由結(jié)果可知:ptr指針存儲的是數(shù)組中的首地址的值,并且這兩個值相同,所以s1和s2確實是指向同一個底層數(shù)組。

但是,這兩個數(shù)組切片的元素不同,這個可以根據(jù)首地址和數(shù)組切片長度len來確定不同的數(shù)組切片應該包含哪些元素,因為s1和s2雖然指向同一個底層數(shù)組,但是二者的len不同。通過這個demo,也驗證了數(shù)組切片傳參方式也是值傳遞。

3.2 數(shù)組切片擴容的情況:

運行以下代碼,思考與不擴容情況的不同之處,以及為什么

func main() {
	s1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
	s2 := append(s1, 10)
	fmt.Println("s1 =", s1)
	fmt.Println("s2 =", s2)
	s2[0] = 0
	fmt.Println("s1 =", s1)
	fmt.Println("s2 =", s2)
}

輸出結(jié)果:

s1 = [1 2 3 4 5 6 7 8 9]

s2 = [1 2 3 4 5 6 7 8 9 10]

s1 = [1 2 3 4 5 6 7 8 9]

s2 = [0 2 3 4 5 6 7 8 9 10]

根據(jù)結(jié)果我們發(fā)現(xiàn),修改s2后,s1并未改變,這說明當append()后,s1和s2并未指向同一個底層數(shù)組,這又是為什么呢?

同樣,我們接著運行以下代碼:

import (
	"fmt"
	"unsafe"
)
type Slice struct {
	ptr unsafe.Pointer // Array pointer
	len int            // slice length
	cap int            // slice capacity
}
func main() {
	s1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
	s2 := append(s1, 10)
	fmt.Println("s1 =", s1)
	fmt.Println("s2 =", s2)
	s2[0] = 0
	fmt.Println("s1 =", s1)
	fmt.Println("s2 =", s2)
	// 把slice轉(zhuǎn)換成自定義的 Slice struct
	slice1 := (*Slice)(unsafe.Pointer(&s1))
	fmt.Printf("ptr:%v len:%v cap:%v \n", slice1.ptr, slice1.len, slice1.cap)
	slice2 := (*Slice)(unsafe.Pointer(&s2))
	fmt.Printf("ptr:%v len:%v cap:%v \n", slice2.ptr, slice2.len, slice2.cap)
}

輸出結(jié)果:

s1 = [1 2 3 4 5 6 7 8 9]

s2 = [1 2 3 4 5 6 7 8 9 10]

s1 = [1 2 3 4 5 6 7 8 9]

s2 = [0 2 3 4 5 6 7 8 9 10]

ptr:0xc04207a000 len:9 cap:9

ptr:0xc04207c000 len:10 cap:18

由結(jié)果可知:append()后,s1和s2確實指向了不同的底層數(shù)組,并且二者的數(shù)組容量cap也不相同了。

過程是這樣的:當append()時,發(fā)現(xiàn)數(shù)組容量不夠用,于是開辟了新的數(shù)組空間,cap變?yōu)樵瓉淼膬杀?,s2指向了這個新的數(shù)組,所以當修改s2時,s1不受影響

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • Go語言實戰(zhàn)之實現(xiàn)均衡器功能

    Go語言實戰(zhàn)之實現(xiàn)均衡器功能

    這篇文章主要為大家詳細介紹了如何利用Golang?實現(xiàn)一個簡單的流浪均衡器,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-04-04
  • Go語言單元測試基礎(chǔ)從入門到放棄

    Go語言單元測試基礎(chǔ)從入門到放棄

    這篇文章主要介紹了Go單元測試基礎(chǔ)從入門到放棄為大家開啟Go語言單元測試第一篇章,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Systemd集成Golang二進制程序的方法

    Systemd集成Golang二進制程序的方法

    這篇文章主要介紹了Systemd集成Golang二進制程序的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-10-10
  • Go語言利用aicli實現(xiàn)輕松調(diào)用DeepSeek和ChatGPT

    Go語言利用aicli實現(xiàn)輕松調(diào)用DeepSeek和ChatGPT

    這篇文章主要為大家介紹了一款用Go語言編寫的AI助手客戶端庫——aicli,該庫不僅支持ChatGPT,還集成了DeepSeek,感興趣的小伙伴可以了解一下
    2025-03-03
  • 深入解析Go語言中crypto/subtle加密庫

    深入解析Go語言中crypto/subtle加密庫

    本文主要介紹了深入解析Go語言中crypto/subtle加密庫,詳細介紹crypto/subtle加密庫主要函數(shù)的用途、工作原理及實際應用,具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • Go語言CSP并發(fā)模型goroutine及channel底層實現(xiàn)原理

    Go語言CSP并發(fā)模型goroutine及channel底層實現(xiàn)原理

    這篇文章主要為大家介紹了Go語言CSP并發(fā)模型goroutine?channel底層實現(xiàn)原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • 一文告訴你大神是如何學習Go語言之make和new

    一文告訴你大神是如何學習Go語言之make和new

    當我們想要在 Go 語言中初始化一個結(jié)構(gòu)時,其實會使用到兩個完全不同的關(guān)鍵字,也就是 make 和 new,同時出現(xiàn)兩個用于『初始化』的關(guān)鍵字對于初學者來說可能會感到非常困惑,不過它們兩者有著卻完全不同的作用,本文就和大家詳細講講
    2023-02-02
  • Goland 關(guān)閉自動移除未使用的包操作

    Goland 關(guān)閉自動移除未使用的包操作

    這篇文章主要介紹了Goland 關(guān)閉自動移除未使用的包操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • golang 歸并排序,快速排序,堆排序的實現(xiàn)

    golang 歸并排序,快速排序,堆排序的實現(xiàn)

    本文主要介紹了golang 歸并排序,快速排序,堆排序的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 帶你在Go?test中體驗jest的安裝使用

    帶你在Go?test中體驗jest的安裝使用

    這篇文章帶你在Go?test中體驗jest的安裝使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08

最新評論

芷江| 达州市| 玉林市| 临沧市| 江源县| 海林市| 冕宁县| 公安县| 丹棱县| 大化| 辉县市| 荣昌县| 双柏县| 南岸区| 庐江县| 玉田县| 布尔津县| 崇信县| 万盛区| 营山县| 盐边县| 阿鲁科尔沁旗| 嘉善县| 太白县| 桃源县| 尚义县| 莎车县| 静乐县| 花垣县| 建德市| 浙江省| 肃宁县| 绥德县| 巴彦县| 富源县| 漠河县| 凯里市| 云龙县| 沙雅县| 绥棱县| 沁阳市|