Golang中的Slice與數組

来源:https://www.cnblogs.com/alienwu/archive/2020/02/25/12364390.html
-Advertisement-
Play Games

1.Golang中的數組 數組是一種具有固定長度的基本數據結構,在golang中與C語言一樣數組一旦創建了它的長度就不允許改變,數組的空餘位置用0填補,不允許數組越界。 數組的一些基本操作: 1.創建數組: func main() { var arr1 = [...]int{1,2,3,4} //[ ...


1.Golang中的數組

    數組是一種具有固定長度的基本數據結構,在golang中與C語言一樣數組一旦創建了它的長度就不允許改變,數組的空餘位置用0填補,不允許數組越界。

     數組的一些基本操作:

     1.創建數組:

 

func main() {
	var arr1 = [...]int{1,2,3,4}  //[...]預設為元素的數量即為數組的長度
	fmt.Println(len(arr1)) //4
	arr1[4] = 5    //panic 數組越界
	fmt.Println(arr1)
	var arr2 = [10]int{1,2,3,4}
	fmt.Println(arr2)  //[1 2 3 4 0 0 0 0 0 0]
}

  2.數組是值拷貝傳遞:

func main() {
	var arr = [10]int{4,5,7,11,8,9}
	fmt.Println(arr) //[4,5,7,11,8,9,0,0,0,0]
	//驗證數組是值拷貝傳遞
	AddOne(arr)
	fmt.Println(arr)  //[4,5,7,11,8,9,0,0,0,0]
}

func AddOne(arr [10]int){
	arr[9] = 999999
	fmt.Println(arr)  //[4,5,7,11,8,9,0,0,0,999999]
}

2.Golang中的切片(slice) 

 

 

     1.首先看看slice的源碼結構:

type slice struct {
	array unsafe.Pointer
	len   int
	cap   int
}

  slice是一個特殊的引用類型,但是它自身也是個結構體

       屬性len表示可用元素數量,讀寫操作不能超過這個限制,不然就會panic

       屬性cap表示最大擴張容量,當然這個擴張容量也不是無限的擴張,它是受到了底層數組array的長度限制,超出了底層array的長度就會panic

     2.slice的創建:

 

func main() {
     var arr = [...]int{0,1,2,3,4,5,6}
     slice1 := arr[1:4:5]   //{low:high:max}  最多再擴張一個元素
     //max超出 len(arr)
     //slice2 := arr[1:4:7]  //panic
     fmt.Println(slice1)  //[1,2,3]
     slice3 := slice1[1:3:4] //[2,3]  大於4會panic
     fmt.Println(slice3)
}

 

 上面代碼中創建了一個長度為7的數組arr,同時創建一個基於數組arr的切片slice1,切片引用了數組的index=1到index=3之間的元素,同時也允許切片最大擴張1個元素大小的空間。如果這個擴張空間大於7那麼程式就會panic。最後創建了一個基於slice1延申的一個切片slice2,它引用了切片的index=1到index=3之間的元素,由於slice1最大擴容1個元素,因此slice2也最多擴容一個元素,超過了會panic。

 

 

    創建基於底層數組的slice,其cap取值在: len<=cap<=len(arr)之間

    創建基於一個切片的slice,其cap取值在: len(slice1)<=cap<=cap(slice1)之間

   3.slice使用make創建

 

func main() {
     var slice = make([]int,3,5)  //len=3,cap=5
     fmt.Println(slice)     //[0,0,0]
     slice2:=slice[:5]      //slice實現了對slice的擴容,切片長度變為5
     fmt.Println(slice2)   //[0,0,0,0,0]
}

 

   4.切片作為參數傳遞

func main() {
     var slice = make([]int,3,5)  //len=3,cap=5
     fmt.Println(slice)     //[0,0,0]
     slice2:=slice[:5]      //slice實現了對slice的擴容,切片長度變為5
     fmt.Println(slice2)   //[0,0,0,0,0]

     slice[0] = 999        //這裡slice和slice的index=0位置都是999  因為他們引用的底層數組的index=0位置都是999
     fmt.Println(slice)
     fmt.Println(slice2)

     AddOne(slice)    //[8888,0,0]
     fmt.Println(slice)  //[8888,0,0]
     fmt.Println(slice2)  //[8888,0,0,0]
}

func AddOne(s []int){
	s[0] = 8888
	fmt.Println(s)
}

  因為切片是個引用類型,所以它作為參數傳遞給函數,函數操作的實質是底層數組

 

3.Golang中的切片追加append()

 

func main() {
     var arr = [...]int{1,2,3,4}
     fmt.Println(arr)  //[1,2,3,4]
     slice := arr[:]
     fmt.Println(slice) //[1,2,3,4]
     slice = append(slice,[]int{5,6,7}...)  //此時slice的引用地址已經發生改變了,它引用的底層數組再也不是arr了,而是一個新的數組newarr[1,2,3,4,5,6,7]
     fmt.Println(slice)  //[1,2,3,4,5,6,7]
     //驗證slice引用的地址已經發生改變
     slice[0] = 666
     fmt.Println(arr)  //[1,2,3,4]
     fmt.Println(slice) //[666,2,3,4,5,6,7]
}

 

  這裡由於slice進行追加的元素超出了原來數組的大小,因此go內部會幫我們創建一個新的底層數組,而slice的引用地址不再是arr了,變成了新創建的數組。

       還有一種情況就是當slice進行追加的時候沒有超出原來數組的大小的時候,其引用地址沒有發生改變

func main() {
     var arr = [6]int{1,2,3,4}
     fmt.Println(arr)  //[1,2,3,4,0,0]
     slice := arr[:4]
     fmt.Println(slice) //[1,2,3,4]
     slice = append(slice,5)
     fmt.Println(arr) //[1,2,3,4,5,0]
     fmt.Println(slice)  //[1,2,3,4,5]
}

4.總結

    (1)go是有數組的,只是平時用切片比較多。數組大小一旦創建就不能改變,數組長度大於元素個數的時候會用0補位,這跟其他語言是相通的。

     (2)切片slice可以看作是對數組的一切操作,它是一個引用數據類型,其數據結構包括底層數組的地址,以及元素可操作長度len或可擴容長度cap。

     (3)要想突破slice的擴容cap限制進行無限擴容就需要使用append()函數進行操作。如果append追加的元素後slice的總長度不超過底層數組的總長度,那麼slice引用的地址不會發生改變,反之引用地址會           變成新的數組的地址。

     (4)slice是一個抽象的概念,它存在的意義在於方便對一個順序結構進行一些方便操作,例如查找,排序,追加等等,這個類似於python的list。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • pyqt5 簡介 pyqt5是一套Python綁定Digia QT5應用的框架,可用於Python2和3。pyqt5做為Python的一個模塊,擁有620多個類和6000個函數與方法,它是跨平臺的工具包,可以運行在Windows,Mac OS,UNIX等多個平臺。 本文參考了 pyqt5包含的模塊 ...
  • 2017年開始實習,現已2020年。三年又三年。今天我刪掉無知的從前,進入新世界。 無論活的多累 做人不進則退 只能自我激勵 將這當做基地 ...
  • 一、Request模塊 1.HTTP for Humans,更簡潔更友好 2.繼承了urllib所有的特征 3.底層使用的是urllib3 4.​開源地址:https://github.com/requests/requests 5.中文文檔​:https://requests.readthedoc ...
  • 在python中除了print函數之外,len函數和type函數應該算是使用最頻繁的API了,操作都比較簡單。 一.len函數簡介 返回對象的長度(項目數)參數可以是序列(例如字元串str、元組tuple、列表list)或集合(例如字典dict、集合set或凍結集合frozenset) 語法: le ...
  • C++常見編程 獲取當前系統時間 文章首發https://www.cppentry.com 本文主要使用time() 及strftime() 函數 C++系統和時間相關的函數基本上都是使用C語言提供的標準介面 在程式中獲取系統時間是常見的操作,很多情況下使用系統提供的time函數即可獲取。 time ...
  • 不知道你是否遇到過面試官讓你手寫生產者消費者代碼。別說,前段時間有小伙伴還真的遇到了這種情況。當時是一臉懵逼。 但是,俗話說,從哪裡跌倒就要從哪裡爬起來。既然這次被問到了,那就回去好好研究一下,爭取下一次不再被虐唄。 於是,今天我決定手敲一個生產者消費者模式壓壓驚。(因為我也不想以後被面試官血虐啊) ...
  • Golang中內置了對單元測試的支持,不需要像Java一樣引入第三方Jar才能進行測試,下麵將分別介紹Golang所支持的幾種測試; 一、測試類型 Golang中單元測試有功能測試、基準測試、示例測試或稱示例函數三種; 功能測試必須以TestXXX函數名出現,基準測試必須以BenchmarkXXX函 ...
  • python的sys模塊是與python解釋器交互的一個介面,提供對解釋器使用或維護的一些變數的訪問,即與解釋器強烈交互的函數。 sys模塊的常用函數: 1.sys.argv:命令行參數列表。第一個元素是腳本的名稱,後面是終端傳入的值;可以在執行整個程式前通過終端傳入參數,然後執行程式,實現從程式外 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...