Go語言-切片底層探索 —— 補充篇:切片和底層數組到底是什么關系?

之前的切片探索中,上篇通過一道算法題目,了解到切片的兩大特性:一是:切片是引用類型,指向底層數組,修改其底層數組的時候,會影響切片中的值。二是:向切片中添加元素的時候,切片可能會發生擴容,改變其底層指向的數組。在下篇中,我們談到了切片的底層實現原理以及擴容機制。在之后的學習中,切片的應用場景比較多,自己也有了一些新的發現,于是形成補充篇這個文章。接下來我會從切片的幾種創建方式說明切片和底層數組之間的關系、切片作為函數的參數時,實際上傳遞的是什么?
上下兩篇:
1.GO語言-切片底層探索(上)-CSDN博客
2.GO語言-切片底層探索(下)-CSDN博客

1. 查看切片底層依托的數組

func main() {//切片slice1基于array數組創建的array := [7]int{1, 2, 3, 4, 5, 0, 1}slice1 := array[3:5]//查看array數組的信息 [1 2 3 4 5 0 0] 7 7fmt.Println(array, len(array), cap(array))//查看slice1切片的信息 [4 5] 2 4fmt.Println(slice1[:], len(slice1[:]), cap(slice1[:]))//查看slice1切片依托底層數組的信息 [4 5 0 1] 4 4fmt.Println(slice1[:cap(slice1)], len(slice1[:cap(slice1)]), cap(slice1[:cap(slice1)]))
}

?在上面的代碼中,我們發現一個奇怪的現象:當我們使用切片表達式slice1[:]和slice1[:cap(slice1)]所取到的值是完全不同的。

我們常用到的切片表達式是slice[low:high]這種兩個參數的形式,我們稱其為簡單切片表達式。此外還有一種三個參數形式的切片表達式,我們稱其為擴展切片表達式,但是一般不經常使用,這里權當擴展一下。在簡單切片表達式中,切片的長度length = high-low,切片的容量cap = 底層數組的長度-low。這里的low和high都是可以省略的,如果省略low則默認為0,如果省略high則默認為切片的長度,而不是容量。

slice1[:]實際上取的是切片的范圍,也就是從切片的下標0到切片的長度-1。而slice1[:cap(slice1)]底層數組的范圍,從slice1所依托得底層數組從下標low(這里是3,因為我們的slice1= array[3:5]),到底層數組末尾。

雖然我們在項目中一般不使用slice[:cap(slice)]這種形式,但是我們知道如果通過獲取切片所依托的底層數組的方法,可以幫助我們更加清晰地理解切片和底層數組的關系,以及切片中的len和cap實際代表的是什么!

2.?切片和底層數組的關系

  1. 直接賦值方式?slice:= []int{1,2,3,4,5}
  2. make字面量方式 slice:= make([]int,0,10)
  3. 使用切片表達式根據切片或數組生成 slice:= array0[1:3]

通過之前的文章,我們知道,切片是依托于數組實現的,相比于數組而言,切片在容量不足的時候,會進行自動擴容,更具有靈活性。我們一般都是通過以上三種方式創建切片的,這三種不同的創建方式,將形成三種不同的(切片和其底層數組之間的)關系。

  1. 直接賦值創建方式,這種方式創建出來的切片長度等于容量,此時如果我們向切片中添加一個新的元素,就會觸發擴容機制,改變切片指向的底層數組。
  2. ?make字面量方式 slice:= make([]int,0,10),通過make創建切片,可以指定切片的長度和容量(底層數組的長度),后續向切片中添加元素的個數,如果沒有超過10就不會發生擴容。通過提前指定切片的容量,可以減少程序運行過程中,切片擴容帶來的資源消耗。
  3. 使用切片表達式根據切片或數組生成 slice:= array0[low:high]。使用切片表達式創建的切片,其長度為high-low,容量是底層數組的長度-low。

3. 切片作為函數的參數時,傳遞的是對底層數組的引用

func main() {baseArray := [5]int{1, 2, 3, 4, 5}//基于baseArray創建sliceslice := baseArray[:] modifySlice(slice, 0)fmt.Println(slice, len(slice), cap(slice))             // 輸出 [100 2 3 4 5]fmt.Println(baseArray, len(baseArray), cap(baseArray)) // 輸出 [100 2 3 4 5]
}func modifySlice(slice []int, index int) {slice[index] = 100
}

在代碼中,我們基于baseArray創建slice,我們發現當傳入的切片在函數中修改時,其依賴的底層數組也發生了修改。這說明,切片作為函數的參數時,實際上傳遞是對底層數組的引用。如果我們在函數的操作導致切片進行了擴容,那么我們的底層數組中的值將不會再發生變化了。

測試如下:

func main() {baseArray := [5]int{1, 2, 3, 4, 5}//基于baseArray創建sliceslice := baseArray[:]modifySlice(slice, 0)fmt.Println(slice, len(slice), cap(slice))             // 輸出 [100 2 3 4 5]fmt.Println(baseArray, len(baseArray), cap(baseArray)) // 輸出 [100 2 3 4 5]
}func modifySlice(slice []int, index int) {slice[index] = 100       //baseArray[index]被修改slice = append(slice, 1) //擴容,底層數組改變slice[index] = 1000      //baseArray[index]值不變fmt.Println(slice, len(slice), cap(slice)) //[1000 2 3 4 5 1] 6 10
}

4. 總結

在這篇博客中,我們主要講解切片和底層數組之間的關系,并且通過切片的三種創建方式來進行詳細的說明。我們在使用切片的時候,一定要注意切片擴容后,其底層指向的數組會發生變化,對切片的修改將不再作用與原來的底層數組。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/20872.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/20872.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/20872.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

半導體光子電學期末筆記1: 電磁光學基本理論

Chapter 2: 電磁光學基本理論 電磁光學理論概述 真空中麥克斯韋方程組[p9] 在自由空間中,麥克斯韋方程組可以寫成如下形式: { ? H ? 0 ? E ? t (1) ? E ? μ 0 ? H ? t (2) ? ? E 0 (3) ? ? H 0 (4) \begin{cases} \nabla \times \…

Java——異常詳解

異常五個主要關鍵字:throw、try、catch、finally、throws 1. 異常的概念與體系結構 1.1 異常的概念 在Java中,程序執行過程中發生的不正常行為被稱為異常,如: 1. 算數異常 public static void main(String[] args) {System.ou…

基于MingGW64 GCC編譯Windows平臺上的 libuvc

安裝cmake 打開cmake官網 https://cmake.org/download/,下載安裝包: 安裝時選擇將cmake加到系統環境變量里。安裝完成后在新的CMD命令窗口執行cmake --version可看到輸出: D:\>cmake --version cmake version 3.29.3 CMake suite mainta…

牛客網刷題 | BC108 反斜線形圖案

目前主要分為三個專欄,后續還會添加: 專欄如下: C語言刷題解析 C語言系列文章 我的成長經歷 感謝閱讀! 初來乍到,如有錯誤請指出,感謝! 描述 KiKi學習了循環&am…

社交媒體數據恢復:Voxer

一、Voxer數據恢復教程 了解Voxer應用 Voxer是一款專門為iPhone和Android智能手機設計的免費對講機應用,為用戶提供即時的語音、文本、照片等信息發送和接收服務。該應用有點類似短信服務,但用聲音代替文本。當你下載之后,如果不邀請朋友&a…

Github查詢語法

轉載自link 基礎查詢結構 一個關鍵詞會匹配文件內容或文件路徑。 多個關鍵詞會匹配文件內容,只要包含關鍵詞,就會出現在搜索結果中,不論前后順序,是否是一個單詞(多個關鍵詞之間沒有空格)。 還可以使用…

Java中的JVM是什么?簡要說明其工作原理

Java虛擬機(JVM)概述 Java虛擬機(Java Virtual Machine,JVM)是Java技術的核心部分。它是一個抽象的計算機,可以解釋和執行Java字節碼。JVM提供了一個運行Java程序的環境,使得Java程序可以在各種…

【面試】字節碼文件是跨平臺的嗎?

目錄 1. 說明 1. 說明 1.字節碼文件(.class文件)是跨平臺的。2.字節碼文件是Java源代碼經過Java編譯器(javac)編譯后生成的中間代碼文件,這些包含了Java虛擬機(JVM)指令,而不是特定…

重復文件怎么查找并清理?電腦重復文件清理工具分享:4個

在日常使用電腦的過程中,我們不可避免地會遇到各種重復文件的問題。這些重復文件不僅占據了寶貴的存儲空間,還可能導致系統性能下降,甚至引發一些不必要的問題。因此,如何有效地查找并清理這些重復文件成為了許多用戶關注的焦點。…

計算 x 的二進制表示中 1 的個數

計算 x 的二進制表示中 1 的個數 代碼如下: int func(int x){int countx 0;while (x>0){countx;x x & (x - 1);}return countx;} 完整代碼: using System; using System.Collections.Generic; using System.ComponentModel; using System.Dat…

STM32基于HAL庫的HC-SR04模塊超聲波測距

文章目錄 一、HC-SR04模塊介紹二、創建工程1.選擇芯片2.配置RCC、SY![在這里插入圖片描述](https://img-blog.csdnimg.cn/direct/9d2a5b883f0e409eabb804e6da861277.png)3.配置串口14.配置定時器5.配置GPIO 三、Keil代碼1.勾選Use MicroLIB2.創建SR04.c和SR04.h文件3.其他代碼 …

html three.js 引入.stl模型示例

1.新建一個模塊用于放置模型 <div id"chart_map" style"width:800px;height:500px"></div> 2. 引入代碼根據需求更改 <!-- 在head或body標簽內加入以下鏈接 --> <script src"https://cdn.jsdelivr.net/npm/three0.137/build/t…

算法題-字符串排序

題目描述 給定n個字符串&#xff0c;請對n個字符串按照字典序排列。 輸入描述: 輸入第一行為一個正整數n(1≤n≤1000),下面n行為n個字符串(字符串長度≤100),字符串中只含有大小寫字母。 輸出描述: 數據輸出n行&#xff0c;輸出結果為按照字典序排列的字符串。 輸入 #輸…

2.7HDR與LDR

一、基本概念 1.基本概念 動態范圍&#xff08;Dynamic Range&#xff09; 最高亮度 / 最低亮度 HDR High Dynamic RangeLDR Low Dynamic Range HDR與LDR和Tonemapping的對應關系&#xff1a; 我們常用的各種顯示器屏幕&#xff0c;由于不同的廠家不同的工藝導致它們的…

HALCON-從入門到入門-軟件界面介紹

1.廢話 從halcon12到halcon23&#xff0c;開發的IDE界面大差不差&#xff0c;簡單說下界面上不同功能按鍵的分布&#xff0c;以及一些快捷鍵啥的&#xff0c;要是還有我沒有總結到的&#xff0c;又比較好用的&#xff0c;歡迎大家補充一下。 1.菜單欄 從上看到下&#xff0c;…

如何從0到設計一個CRM系統

什么是CRM 設計開始之前&#xff0c;先來了解一下什么是CRM。CRM&#xff08;Customer Relationship Management&#xff09;是指通過建立和維護與客戶的良好關系&#xff0c;達到滿足客戶需求、提高客戶滿意度、增加業務收入的一種管理方法和策略。CRM涉及到跟蹤和管理客戶的所…

python深度學習入門-從零構建CNN和RNN

文章目錄 第1章 基本概念1.1. 導數1.2. 鏈式法則1.3. 多輸入函數的導數1.4. 多輸入向量函數的導數1.5. 向量函數及其導數&#xff1a; 再進一步1.6. 包含兩個二維矩陣數據的計算圖 第2章 基本原理2.1. 監督學習概述2.2. 監督學習模型2.3. 線性回歸2.3.1. 線性回歸&#xff1a; …

[激光原理與應用-94]:電控 - 低噪聲運放的原理

目錄 一、什么是低噪聲運放 1.1 什么是低噪聲水平 1.2 什么是高增益 在電子工程中的應用 在通信領域的應用 在音頻和視頻處理中的應用 注意事項 1.3 什么是寬帶寬 1.4 什么是低偏置電流 重要性 特點 解決方法 應用 二、低噪聲運放的原理圖 1. 基本構成 2. 設計…

HTML5新元素探索:重塑網頁結構與功能的革新

隨著互聯網技術的飛速發展&#xff0c;HTML5作為新一代超文本標記語言標準&#xff0c;不僅增強了對多媒體內容的支持&#xff0c;還引入了一系列新元素&#xff0c;旨在使網頁結構更加語義化、可訪問性更強。本文將深入探討幾個核心的新元素&#xff0c;通過代碼示例展示它們如…

22data 腳本語言基礎——Python

橫線為沒講到的。 1. 基礎語法 變量&#xff1a;變量的聲明和使用。 數據類型&#xff1a;整數&#xff08;int&#xff09;、浮點數&#xff08;float&#xff09;、字符串&#xff08;str&#xff09;、布爾值&#xff08;bool&#xff09;等。 運算符&#xff1a;算術運算符…