Go語言數組與切片學習總結

来源:https://www.cnblogs.com/sillyfox/archive/2023/10/28/17794397.html
-Advertisement-
Play Games

一.數組 數組的定義:相同類型的數據集合 go語言中數組的索引從0開始 沒有賦值的數值型數組,預設值為0 數組一旦被創建,它的大小就是不可改變的 (1)聲明數組與列印 var 變數名 [大小]變數類型 //數組的聲明 var nums [4]int //數組的賦值 nums[0] = 1 nums[ ...


一.數組

  • 數組的定義:相同類型的數據集合
  • go語言中數組的索引從0開始
  • 沒有賦值的數值型數組,預設值為0
  • 數組一旦被創建,它的大小就是不可改變的

(1)聲明數組與列印

var 變數名 [大小]變數類型

 //數組的聲明
var nums [4]int       

//數組的賦值
nums[0] = 1
nums[1] = 2
nums[2] = 3
nums[3] = 4

/***************數組的列印*************/
fmt.Printf("%T\n", nums)     //列印數組的類型:[4]int
fmt.Println(nums[3])         //列印單個數組的值:4
fmt.Println("長度:", len(nums))    //列印數組的長度:4
fmt.Println("容量:", cap(nums))    //列印數組的容量:4

(2)數組的初始化

在go語言中,數組有多種初始化方式。

  • 常量初始化定義數組
  • 快速的定義數組
  • 定義不確定長度的數組
  • 給指定下標進行賦值操作
	//1、常量的初始化定義數組
	var arrs1 = [5]int{1, 2, 3, 4, 5}

	//2、快速定義數組
	arrs2 := [5]int{6, 7, 8, 9, 10}

	//3、定義不確定長度的數組
	arrs3 := [...]string{"hello", "xuexiangban", "kuangshenshuo"}

	//4、給指定下標進行賦值操作
	arrs4 := [5]int{1: 100, 3: 200}//給下標為1賦值為100,下標為3賦值為200

(3)數組的遍歷

  • for迴圈遍歷
	//1、for迴圈遍曆數組
	arr1 := [5]int{1, 2, 3, 4, 5}    //創建數組
	for i := 0; i < len(arr1); i++ {
		fmt.Println(arr1[i])
	}
/*輸出結果:
1
2
3
4
5
*/
  • for-range遍歷方式
	//2、forage迴圈遍曆數組
	for index, value := range arr1 { //index下標,value對應的值
		fmt.Println(index, value)
	}
/*輸出結果:
0 1
1 2
2 3
3 4
4 5
*/

(4)數組是值傳遞類型

  • 在go語言中,數組被看作是值傳遞類型,因此數組之間可以直接相互賦值
	arr1 := [3]int{1, 2, 3}         //創建數組1:整型
	arr2 := [2]string{"hello", "xuexiangban"}   //創建數組2:字元型
	arr3 := arr1                //創建數組3直接被賦值數組1
	fmt.Println(arr1, arr3)   //列印結果:[1 2 3] [1 2 3]
	arr3 = [3]int{4, 5, 6}    //重新賦值
	fmt.Println(arr1, arr3) //[1 2 3] [4 5 6]

(5)多維數組

  • go語言支持多維數組,以下為常用的多維數組聲明方式
var 變數名[SIZE1][SIZE2]...[SIZEN]變數類型
  • 多維數組定義示例:
	arr := [3][4]int{
		{1, 2, 3, 4},
		{5, 6, 7, 8},
		{9, 10, 11, 12},
	}
  • 多維數組使用示例
	//forage迴圈輸出
	for _, i := range arr {
		fmt.Println(i)        //列印外層
		fmt.Println("=========")   //列印內層
		for _, i2 := range i {
			fmt.Println(i2)
		}
	}

/*列印結果:
[1 2 3 4]
=========
1
2
3
4
[5 6 7 8]
=========
5
6
7
8
[9 10 11 12]
=========
9
10
11
12

*/

二.切片

Go語言切片是對數組的抽象

go語言數組的長度是不可改變的切片的長度是不固定的可以追加元素,在追加時可能使切片的容量增大

切片是一種方便、靈活且強大的包裝器,切片本身沒有任何數據,他們只是對現有數組的引用

切片與數組相比,不需要設定長度,在[]中不用設定值,相對來說比較自由

(1)定義創建切片

切片與數組在定義時不同,可以不用指定長度容量

	//1、定義一個切片,裡面不添加數據,列印輸出
	s1 := []int{}
	fmt.Println(s1) //輸出結果:[]

	//2、定義切片向裡面添加數據,列印輸出類型
	s2 := []int{1, 2, 3}
	fmt.Println(s2)         //輸出結果:[1 2 3]
	fmt.Printf("%T", s2)   //輸出結果[]int

補充:長度(length)和容量(cap)區別

  • 長度(length)指切片中當前包含的元素個數。使用內置函數len()可以獲取切片的長度。

  • 容量(capacity)指分配給切片的底層數組中可用於存儲元素的空間大小。容量至少等於切片長度,但可能會更大以容納未來的增長。使用內置函數cap()可以獲取切片的容量。

  • 在創建切片的時候,可以只指定長度也可以同時指定長度和容量。當只指定長度時,切片的容量與長度相等。當同時指定長度和容量時,切片的容量可以大於長度。

(2)make函數創建切片

make函數創建切片,可以指定切片的長度和容量

make([]T,length,capactity)   //類型,長度,容量
  • 使用示例
	//1、通過make函數來創建切片
	s1 := make([]int, 5, 10) //長度:5,容量為10
	//2、給切片裡面的元素進行賦值
	s1[0] = 100
	//3、列印輸出長度,容量
	fmt.Println(s1)
	fmt.Println("長度:", len(s1))
	fmt.Println("容量:", cap(s1))

(3)切片擴容append

  • 註意:追加數據超過容量後,容量只會2倍擴容地址會發生改變
	//1、創建一個切片s1
	s1 := make([]int, 2, 4)
	fmt.Println("追加數據前的長度和容量:", len(s1), cap(s1))
	//2、s1通過append追加數據
	s1 = append(s1, 1, 2, 3, 4) //追加數據,不是添加數據
	fmt.Println(s1)
	fmt.Println("追加數據後的長度和容量:", len(s1), cap(s1))

	//	3、創建一個s2,將s2中數據追加到s1
	s2 := make([]int, 3, 3)
	s2 = []int{1, 2, 3}
	s1 = append(s1, s2...) //將s2裡面的數據追加到s1
	fmt.Println(s1)

(4)在已有數組上創建切片

從已有的數組上,直接創建切片,該切片的底層數組就是當前的數組,長度是從start到end切到的數據量,但是容量從start到數組的末尾。

從數組上創建的切片,地址與數組是一樣的,因此修改數組或切片的某個值,對應的數組/切片的值也會改變

slice := arr[start:end]

	//定義數組和其切片
	arr := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

	s1 := arr[:5]  //切片從1-5 [1 2 3 4 5]
	s2 := arr[4:8] //[5 6 7 8]
	s3 := arr[5:]  //[6 7 8 9 10]
	s4 := arr[:]   //[1 2 3 4 5 6 7 8 9 10]
	fmt.Println(s1)   //[1 2 3 4 5]
	fmt.Println(s2)   //[5 6 7 8]
	fmt.Println(s3)   //[6 7 8 9 10]
	fmt.Println(s4)   //[1 2 3 4 5 6 7 8 9 10]

	//修改數組的某個值
	arr[0] = 100 //將數組元素值進行更換
	fmt.Println(arr)      //[100 2 3 4 5 6 7 8 9 10]
	fmt.Println(s1)	       //[100 2 3 4 5 6 7 8 9 10]

	//修改切片的某個值
	s1[1] = 100 
	fmt.Println(arr)    //[100 100 3 4 5 6 7 8 9 10]
	fmt.Println(s1)	    //[100 100 3 4 5]

    //查看數組和對應切片的地址
	fmt.Printf("%p\n", s1)   //0xc0000ac0f0
	fmt.Printf("%p\n", &arr)  //0xc0000ac0f0

(5)切片是引用類型

  • 與數組不同,數組是值傳遞類型,而切片是引用類型
  • 數組之間可以直接賦值,改變其中一個數組的值,另一個數組的值不會發生改變
  • 切片之間若直接賦值,則改變其中一個切片的值,另一個切片的值同樣發生改變
	s1 := []int{1, 2, 3, 4, 5}
	s2 := s1
	s2[0] = 100
	fmt.Println(s1, s2)          //切片2里元素髮生變化,切片1也會跟隨著變化
	fmt.Printf("%p\t%p", s1, s2) //說明切片的copy指向的是地址

(6)copy深拷貝與淺拷貝

  • 深拷貝:拷貝的是數據本身
  • 淺拷貝:拷貝的是數據的地址,會導致多個變數指向同一塊記憶體
  • 引用類型的數據,預設都是淺拷貝,如切片,集合
  • 可以用copy強制實現深拷貝

實現切片的深拷貝

	//1、通過for迴圈實現切片的深拷貝
	s1 := []int{1, 2, 3, 4}
	s2 := make([]int, 0, 0)
	for i := 0; i < len(s1); i++ {
		s2 = append(s2, s1[i])
	}
	fmt.Println(s1, s2)
	//2、通過copy操作實現深拷貝
	s3 := []int{5, 6, 7, 8}
	fmt.Println(s1, s3)
	copy(s3, s1) //(接收者,傳遞者) 將s1 copy 給s3
	fmt.Println(s1, s3)

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

-Advertisement-
Play Games
更多相關文章
  • 1. 基本信息 高性能MySQL:經過大規模運維驗證的策略(第4版) High Performance MySQL, Fourth Edition [美] Silvia Botros(西爾維亞·博特羅斯);Jeremy Tinley(傑里米·廷利) 電子工業出版社,2022年10月出版 1.1. 讀 ...
  • vue2和vue3都是前端JavaScript框架,基本概念和功能大部分都相同,它們的區別主要在語法、原理、生態以及打包四個方面. 語法: Vue.js 2使用基於Object.defineProperty的雙向綁定來追蹤變化,而Vue.js 3採用Proxy來實現響應式變化追蹤,這提高了性能並允許 ...
  • 線程間通信 多線程編程步驟(中) 第一,創建資源類,創建屬性和操作方法;第二,在資源操作方法,1)判斷 2)工作 3)通知;第三,創建多線程調用資源類的方法。 案例 要求,有兩個線程,實現對一個初始值為0的變數,一個線程對值+1,一個線程對值-1。 代碼實現 /** * @author 長名06 * ...
  • 今天我們來看看Dart語言的一個有趣的特性——可調用對象。對象也可以像函數那樣被調用,這個特性是怎麼用的呢…… ...
  • 基礎知識 機器語言 機器語言是機器指令的集合 機器指令是一臺機器可以正確執行的命令 機器指令由一串二進位數表示 彙編語言 彙編語言的主體是彙編指令 彙編指令是機器指令便於記憶的書寫格式 彙編指令是機器指令的助記符 彙編語言的組成 彙編指令:機器碼的助記符,有對應的機器碼 偽指令::沒有對應的機器碼, ...
  • 可移動嵌入式設備是數據客戶端的一種表現形式。軟體的代碼編寫之後是運行在伺服器之上, 伺服器的數據為客戶端提供服務的模式為伺服器客戶端模式,server2client 架構。伺服器可以是大型的機器,也可以是小型機,主要看數據處理量和用戶量的大小。一臺電腦其實就是一臺簡單的伺服器,電腦的存在是使用中 ...
  • 一些研發工程師在Springboot註意點1. 正確設計代碼目錄結構雖然您有很大的自由度,但有一些基本規則值得遵循來設計您的源代碼結構。避免使用預設包。確保所有內容(包括入口點)都在命名良好的包中,這樣您就可以避免與組裝和組件掃描相關的意外情況;將 Application.java(應用程式的入口類 ...
  • 變數只在創建它的區域內可用。這被稱為作用域。 局部作用域 在函數內部創建的變數屬於該函數的局部作用域,並且只能在該函數內部使用。 示例:在函數內部創建的變數在該函數內部可用: def myfunc(): x = 300 print(x) myfunc() 函數內部的函數 如上面的示例所解釋的那樣,變 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...