golang的切片

切片

為什么需要切片

  1. 用于元素的個數不確定,所以無法通過數組的形式來進行統計。此時就需要切片
    切片,也因此可以粗略地理解為動態數組
  2. 數組的長度不能用變量來確定,這時候切片slice也就派上用場了

切片地基本介紹

  1. 切片的英文是slice
  2. 切片是數組的一種引用,這也說明切片是引用類型,在傳遞時,遵守引用傳遞的機制
  3. 切片的使用和數組類似,遍歷、求長、訪問都是一樣的
  4. 切片的長度是可變的,因此說切片可以粗略理解為動態數組
  5. 切片定義的語法:
    var 切片名 []類型
    var a []int

切片的快速入門

var arr [5]int = [5]int{1, 2, 45, 6, 3}
a := arr[2:4]
fmt.Println(arr)
fmt.Println(a)
fmt.Printf(“a的長度%d\n”, len(a))
fmt.Printf(“a的容量%d\n”, cap(a))
fmt.Printf(“a指向的地址%v\n”, &a[0])
輸出結果為:
[1 2 45 6 3]
[45 6]
a的長度2
a的容量3
a指向的地址0xc000010240

可見,a := arr[2:4],這段代碼就是將arr數組的下標為2-3的元素。
其中cap()函數是用來求切片容量的,容量是指切片目前最多能存儲的元素個數,并且這個容量是可以動態更改的

切片在內存中的形式

  1. slice在內存中有三個值,一個是slice所指向的第一個元素的地址,一個是這個slice的長度,還有一個是這個slice的容量
  2. 根據這第一個值,我們也很容易判斷出slice是引用類型
  3. 其實,我們可以把slice看成一種結構體struct。其由這三個值組成。
    type slice struct {
    array *[n]T // 指向底層數組的指針
    len int // 當前長度
    cap int // 總容量
    }
  4. 另外,值得注意的一點是,由于slice是引用類型,所以當用slice[1]來修改值時,其所指的地址的值發送改變,也就是原數組的內容也會發送改變
    代碼用例:
    var arr [5]int = [5]int{1, 2, 45, 6, 3}
    a := arr[2:4]
    fmt.Println(arr)
    fmt.Println(a)
    a[0] = 100
    fmt.Println(arr)
    fmt.Println(a)
    輸出結果為:
    [1 2 45 6 3]
    [45 6]
    [1 2 100 6 3]
    [100 6]

切片的使用

  1. 定義一個切片,讓切片去引用一個定義好的數組
  2. 用make來創建切片
    基本語法:var 切片名 []類型 = make([]類型,切片長度,切片容量)
    要求:容量必須大于等于長度
    創建完的切片里的元素都是默認值

這樣定義出來的切片所指向的數組,是對外隱蔽的,只能通過slice來訪問這個數組

  1. 定義切片的時候,直接指定具體的數組
    代碼示例:
    func main() {
    var arr []int = []int{1, 2, 41, 21}
    fmt.Printf(“%v\n”, len(arr))
    fmt.Printf(“%v”, arr)
    }
  2. 方式一和方式二的區別:
    方式一:直接引用數組,是要求先定義好了一個數組,這個數組是可見的
    方式二:用make創建切片的同時,也會創建數組,這個數組是由切片在底層進行維護的數組,是不可見的,只能通過slice來對它進行訪問修改等

切片的遍歷

  1. 傳統for循環
  2. for-range語句遍歷
    func main() {
    var n [5]int = [5]int{2, 12, 31, 12, 45}
    slice1 := n[1:3]
    for i := 0; i < len(slice1); i++ {
    fmt.Printf("%v “, slice1[i])
    }
    fmt.Println()
    for index, value := range slice1 {
    fmt.Printf(”%v,%v ", index, value)
    }
    }

切片的使用細節和注意事項

  1. 切片初始化時,var slice = arr[start:end]

其中切片slice是從arr數組的start下標開始,到end下標結束,但是不將end下標的元素也囊括在內

  1. 在使用切片時,也只能按照0-len(slice)-1的范圍來,不能夠直接來越界初始化,需要先動態增長先
  2. slice :=arr[下標1:下標2]
    1. 如果不寫下標1,默認是0,從頭開始
    2. 如果不寫下標2,默認是end,把最后一位元素也算進去
    3. 所以要想表示切片獲取整個數組,有如下幾種簡寫
      1. slice :=arr[:]
      2. slice :=arr[0:]
      3. slice :=arr[:len(arr)]
  3. cap是一個內置函數,用于計算切片的容量,也就是最大可以存放多少元素
  4. 切片定義完后,本身還是空的,需要讓其引用數組,或者用make函數創建一個空間供切片使用
  5. 切片可以繼續切片
  6. append函數
    1. append的用法
      1. slice = append(slice, elem1, elem2, …)

      給slice切片添加后面幾個元素,這里的…表示的是省略

      1. slice = append(slice, anotherSlice…)

      在slice后面接收另一個切片,這里的…是不能省略的,表示將后面的切片各個元素拆開加入
      不論append的哪種用法,都必須要有接收,不然相當于沒有任何作用,因為append函數并不會去改變原來的切片

    2. 擴不擴容
      1. 當長度在append后>容量時才會擴容,否則不會
        2. 只有在擴容時,才會執行下面的(45678),因為如果不用擴容,就可以直接在原來的切片上更改,不需要額外創建新數組(擁有足夠大的容量)
    3. append函數本質就是對數組的擴容
    4. append函數會創建一個新的數組newarr(是擴容后的大小)
    5. 將slice原來的元素拷貝到newarr
    6. 在newarr上添加新元素
    7. 返回新的切片(指向新數組),比如:slice重新引用到newarr
    8. newarr是底層維護的,程序員不可見
  7. 切片的拷貝
    copy函數
    語法copy(para1,para2)
    para1,para2這兩個都需要是切片,并且是將para2的內容給到para1里面

此處不在乎二者的長度的大小關系,反正就是逐位去拷貝

拷貝并不會使這兩個切片的空間有什么關聯,依然是相互獨立的

  1. 切片是引用類型,所以傳遞時遵循引用傳遞,向函數傳遞切片時,函數內部對切片的操作,也會對外部操作有影響
    代碼示例:
    func test(a []int) {
    a[0] = 100
    }
    func main() {
    var a []int = make([]int, 4, 8)
    a[0] = 1
    a[1] = 2
    a[2] = 3
    a[3] = 4
    fmt.Println(a)
    test(a)
    fmt.Println(a)
    }
    輸出結果:
    [1 2 3 4]
    [100 2 3 4]

string和slice的關系

  1. string的底層是一個byte數組,因此string也可以用切片來處理
  2. string的核心結構:
    type stringStruct struct {
    str unsafe.Pointer // 指向底層字節數組的指針
    len int // 字符串的字節長度(不是字符數)
    }
    這和切片的結構是很像的,只是沒有容量,因為數組的容量大小就是長度大小,因為它長度不可變
  3. string本身是不可變的,不能通過str[0]="1"這種類似形式去修改(和java一樣)
  4. 如果要修改string的值,需要先將string轉換成[]byte或者[]rune,修改完后,再轉成string

有中文的情況轉成[]rune,因為[]rune是按照字符,一個中文占三四個字節

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

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

相關文章

在labview中實現視頻播放

這里分享一個迅雷的視頻播放控件APlayer&#xff0c;非常的好用。具體操作步驟如下&#xff1a; 1.下載控件: 首先下載http://aplayer.open.xunlei.com/codecs.zip&#xff0c;將codecs文件解壓后打開&#xff0c;按快捷鍵contrlA,隨后contrlc復制里面所有的文件&#xff1b;…

ubuntu 22.04 使用yaml文件 修改靜態ip

前提&#xff1a; 啟動服務 sudo systemctl start systemd-networkd 設置開機自啟 sudo systemctl enable systemd-networkd 檢查狀態&#xff08;確保顯示 active (running)&#xff09; sudo systemctl status systemd-networkd 若想停止&#xff1a; 停止當前運行的服務 sud…

閘機控制系統從設計到實現全解析:第 4 篇:Redis 緩存與分布式鎖實現

第 4 篇&#xff1a;Redis 緩存與分布式鎖實現 一、Redis 在系統中的核心作用票證信息緩存&#xff1a;將高頻訪問的票證數據&#xff08;如狀態、有效期&#xff09;緩存至 Redis&#xff0c;減少數據庫查詢&#xff0c;提升驗證響應速度。分布式鎖&#xff1a;在高并發場景下…

北京天津唐山廊坊滄州打撈日記

北京天津唐山廊坊滄州打撈日記 打撈搜蚯蚓疏通 北京&#xff1a;護城河畔的情誼打撈 清晨&#xff0c;北京的護城河在朝陽的映照下泛著微光。我接到一位年輕小伙的電話&#xff0c;聲音中滿是焦急。原來&#xff0c;他與女友在河邊約會時&#xff0c;不小心將女友送他的定情玉佩…

全志刷機工具:PhoenixSuit-全志芯片處理器-刷機工具安裝包及最詳細使用教程指南

全志刷機工具&#xff1a;PhoenixSuit-全志芯片處理器刷機工具安裝包及最詳細使用教程指南&#xff0c;此文章主要是分享機頂盒、電視盒子&#xff0c;全志芯片盒子&#xff08;其中包含全志處理器、全志芯片、全志CPU等等&#xff09;的刷機工具、刷機工具安裝教程以及如何使用…

淺談 VM 橋接模式:讓虛擬機像真實電腦一樣接入網絡

在虛擬化環境中&#xff0c;虛擬機&#xff08;Virtual Machine, VM&#xff09;與外部網絡之間的通信方式有多種&#xff0c;比如 NAT 模式、Host-Only 模式、橋接模式&#xff08;Bridged Networking&#xff09; 等。其中&#xff0c;橋接模式是最接近“真實物理機”網絡行為…

計算機視覺(1)-圖像采集設備選型全景表(工業 + 醫療 + 車載)

圖像采集設備選型全景表&#xff08;工業 醫療 車載&#xff09;一份面向工程師的“場景—設備—協議”速查表1 工業 & 醫療 & 通用場景應用場景主流設備形態接口 / 協議典型性能突出優勢致命短板動態范圍工業檢測AOI / 量測 / 缺陷工業相機 采集卡Camera Link HSCo…

計算機視覺(3)深度學習模型部署平臺技術選型與全棧實踐指南

一、部署平臺概述與分類 深度學習模型部署平臺的分類需兼顧技術特性與應用場景的適配性&#xff0c;基于“技術定位-場景適配”雙維度分類法&#xff0c;可將其劃分為通用開源框架、云廠商服務及專用邊緣工具三大類&#xff0c;各類別在設計目標、核心能力與場景覆蓋上呈現顯著…

Scratch編程:槍戰游戲(附源碼)

&#x1f3ae; 操作說明 W / A / S / D 或 方向鍵&#xff1a;移動 C&#xff1a;滑鏟 空格鍵&#xff1a;取消滑鏟 鼠標點擊&#xff1a;開火 數字鍵 1 / 2 / 3 / 4&#xff1a;切換武器 G&#xff1a;快速使用道具 F&#xff1a;近戰攻擊 Q&#xff1a;瞄準 / 使用技能…

應急響應復現

一、前言&#xff1a;當企業發生黑客入侵、系統崩潰或其它影響業務正常運行的安全事件時&#xff0c;急需第一時間進行處理&#xff0c;使企業的網絡信息系統在最短時間內恢復正常工作&#xff0c;進一步查找入侵來源&#xff0c;還原入侵事故過程&#xff0c;同時給出解決方案…

分布式事務Seata TCC模式篇

介紹 ? 官網: https://seata.apache.org/zh-cn/docs/user/mode/tcc ? 回顧Seata AT 模式基于 支持本地 ACID 事務 的 關系型數據庫&#xff0c;如下&#xff1a; 一階段 prepare 行為&#xff1a;在本地事務中&#xff0c;一并提交業務數據更新和相應回滾日志記錄。二階段 c…

Day37--動態規劃--52. 攜帶研究材料(卡碼網),518. 零錢兌換 II,377. 組合總和 Ⅳ,57. 爬樓梯(卡碼網)

Day37–動態規劃–52. 攜帶研究材料&#xff08;卡碼網&#xff09;&#xff0c;518. 零錢兌換 II&#xff0c;377. 組合總和 Ⅳ&#xff0c;57. 爬樓梯&#xff08;卡碼網&#xff09; 本文全部都是 ” 完全背包 “ 問題&#xff0c;從零到入坑&#xff0c;從入坑到爬出來。 本…

Linux文件操作

Linux文件Linux下的文件類型b 塊設備文件---->存儲類設備&#xff08;硬盤&#xff09;c 字符設備文件--->輸入輸出設備d 目錄文件--->文件夾- 普通文件--> xxx.c xxx.h xxx.txt xxx.jpg xxx.mp4 a.outl 軟鏈接文件-->快捷方式s 套接字文件-->網絡通信p 管道…

Linux epoll 觸發模式詳解:LT vs ET

兩種核心觸發模式 1. 水平觸發 (Level-Triggered, LT) 工作方式: 當文件描述符處于就緒狀態時,epoll 會持續通知 只要狀態未改變,每次調用 epoll_wait 都會返回該描述符 特點: c // 內核處理邏輯 (ep_send_events_proc) if (!(epi->event.events & EPOLLET)) { /…

STM32學習筆記6-TIM-2輸出比較功能

第二部分&#xff0c;定時器的輸出比較功能OC&#xff08;Output Compare&#xff09;輸出比較輸出比較可以通過比較CNT與CCR寄存器值的關系&#xff0c;來對輸出電平進行置1、置0或翻轉的操作&#xff0c;用于輸出一定頻率和占空比的PWM波形每個高級定時器和通用定時器都擁有4…

MATLAB核心技巧:從入門到精通

一 1.數值 顯示 格式 format style 設置 eg: pi format longE; or 2.清除指令 clc 清除命令行窗口 clear 清除工作區 cls 3.搜索路徑設置 path(path,E:\ads\) or addpath 4.M文件 用戶把要實現的命令寫在一個以.m為擴展的文件中&#xff0c;然后由matlab系統進行解讀…

AnyDesk遠程工具免費版,v9.5.110綠色便攜版,秒連遠程桌面,剪貼板同步超實用

[軟件名稱]: AnyDesk遠程工具免費版 [軟件大小]: 7.5 MB [軟件大小]: 夸克網盤 | 百度網盤 軟件介紹 AnyDesk 讓遠程工作變得輕而易舉。無論您身處辦公室的另一端還是世界的另一側&#xff0c;只需在設備上下載、安裝并啟動 AnyDesk.exe&#xff0c;即可輕松訪問遠程屏幕。…

AI: 給Gemini CLI配上“說明書”, 精通的GEMINI.md項目記憶

嘿&#xff0c;各位技術同好&#xff01;今天我們來聊一個能極大提升AI編程助手效率的酷炫功能——Google Gemini CLI 中的 GEMINI.md 文件。 在日常開發中&#xff0c;我們越來越依賴像 Gemini 這樣的 AI 助手來幫我們寫代碼、調試 Bug 甚至重構項目。但大家是否遇到過這種情況…

[激光原理與應用-205]:光學器件 - LD與DFB的比較

一、相同點核心原理均基于半導體材料的受激輻射機制&#xff0c;通過電子-空穴復合產生光子。依賴諧振腔實現光反饋與放大&#xff0c;形成激光振蕩。采用電泵浦方式驅動&#xff0c;電流注入激發載流子&#xff0c;實現粒子數反轉。材料體系主要使用III-V族化合物半導體&#…

Cursor手機版:一半是神,一半是坑

大家好&#xff0c;我是羊仔&#xff0c;專注AI工具、智能體、編程。今天想和大家聊的這個工具&#xff0c;叫Cursor&#xff0c;可能很多朋友已經不陌生了&#xff0c;它作為一款AI原生代碼編輯器&#xff0c;之前可謂是風光無兩。但最近&#xff0c;它又搞了點新花樣&#xf…