go語言基礎|slice入門

slice

slice介紹

slice中文叫切片,是go官方提供的一個可變數組,是一個輕量級的數據結構,功能上和c++的vector,Java的ArrayList差不多。

slice和數組是有一些區別的,是為了彌補數組的一些不足而誕生的數據結構。最大的區別就是數組長度固定,不可擴容,而切片是可以擴容的。也就是這個功能的區別導致了后續一系列的區別,例如在傳參上面,數組是整個數組的值復制過去傳到函數里,而切片則是傳遞指針等。

?func change(arr *[3]int) {arr[0] = 1}func change1(arr [3]int) {arr[0] = 1}func TestName(t *testing.T) {arr := [3]int{1, 2, 3}arr[0] = 2change(&arr)//change1(arr) // 這兩者的結果是不一樣的fmt.Println(arr[0])}

那么slice是什么呢? slice結構體源碼如下:(在runtime/slice.go中)

?type slice struct {array unsafe.Pointer // 指向底層數組的指針len ? int ? ? ? ? ? ?// 當前長度cap ? int ? ? ? ? ? ?// 總容量}

slice擴容機制

1.18之前的方式和現在不太一樣,Go1.18之前切片的擴容是以容量1024為臨界點,當舊容量 < 1024個元素,擴容變成2倍;當舊容量 > 1024個元素,那么會進入一個循環,每次增加25%直到大于期望容量。

?func TestSliceGrowing(t *testing.T) {s := []int{}for i := 0; i < 4098; i++ {s = append(s, i)t.Log(len(s), cap(s))}}?作者:starine鏈接:https://juejin.cn/post/7101928883280150558來源:稀土掘金著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

Go1.18不再以1024為臨界點,而是設定了一個值為256的threshold,以256為臨界點;超過256,不再是每次擴容1/4,而是每次增加(舊容量+3*256)/4;

當新切片需要的容量大于兩倍的舊容量時,則直接按照新切片需要的容量擴容; else: 當原 slice 容量 < threshold 的時候,新 slice 容量變成原來的 2 倍; 當原 slice 容量 > threshold,進入一個循環,每次容量增加(舊容量+3*threshold)/4。

作者:starine 鏈接:https://juejin.cn/post/7101928883280150558 來源:稀土掘金 著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

?func growslice(et *_type, old slice, cap int) slice {//  ......newcap := old.capdoublecap := newcap + newcap ? ?//雙倍擴容(原容量的兩倍)if cap > doublecap { ? //如果所需容量大于 兩倍擴容,則直接擴容到所需容量newcap = cap} else {const threshold = 256 ? //這里設置了一個 閾值 -- 256if old.cap < threshold {        //如果舊容量 小于 256,則兩倍擴容newcap = doublecap ? } else {// 檢查 0 < newcap 以檢測溢出并防止無限循環。for 0 < newcap && newcap < cap { ? //如果新容量 > 0  并且 原容量 小于 所需容量// 從小片的增長2x過渡到大片的增長1.25x。這個公式給出了兩者之間的平滑過渡。(這里的系數會隨著容量的大小發生變化,從2.0到無線接近1.25)newcap += (newcap + 3*threshold) / 4//當newcap計算溢出時,將newcap設置為請求的上限。if newcap <= 0 { ? // 如果發生了溢出,將新容量設置為請求的容量大小newcap = cap}}}}

具體情況如下:

如果請求容量 大于 兩倍現有容量 ,則新容量 直接為請求容量
?否則(請求容量 小于等于 兩倍現有容量) 如果 現有容量 小于 256 ,則新容量是原來的兩倍
?否則:新容量 = 1.25 原容量 + 3/4 閾值

golang slice (切片) 擴容機制詳解(1.18版本后) - 小星code - 博客園

這么設計的目的是為了擴容能平滑,更好地節省內存。

傳參問題

slice被make出來就是一個結構體的實例。當作為一個參數傳遞到方法里,會傳遞一個這個slice實例的值過去,這也是導致slice傳參會有一些列奇怪現象的原因(可以修改值但無法擴容等)。可以修改數值的原因是這個值中的array指針是指向原數組的,但是無法擴容的原因是修改這個值的指針對原slice是無影響的;而傳遞slice指針可以修改成功是因為本質是就是在修改原方法層面的slice,而不是修改傳遞后slice的值。

線程安全性問題

slice是線程不安全的數據結構,因此會存在競態條件(race condition),處理原則要么只讀,要么加鎖

Slice 的底層是 數組指針 + len + cap,這幾個在并發時候都可能出現競態條件。

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

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

相關文章

網絡攻防技術九:網絡監聽技術

文章目錄 一、網絡監聽概述二、網絡流量劫持三、數據采集與解析四、網絡監聽檢測與防范1、檢測實施監聽主機2、防范網絡通信被監聽 一、網絡監聽概述 主要解決問題&#xff1a;網絡流量劫持、在監聽點上采集并分析網絡數據。主要涉及網卡數據采集、協議分析技術。 二、網絡流量…

Cat.1與Cat.4區別及應用場景

Cat.1 和 Cat.4 都是 LTE&#xff08;4G&#xff09;網絡中的終端設備類別&#xff0c;主要區別在于 數據傳輸速率、復雜度和功耗&#xff0c;這直接影響了它們的應用場景和成本。 以下是它們的主要區別&#xff1a; 數據傳輸速率 (核心區別)&#xff1a; Cat.1 (Category 1)&…

【后端高階面經:架構篇】51、搜索引擎架構與排序算法:面試關鍵知識點全解析

一、搜索引擎核心基石&#xff1a;倒排索引技術深度解析 &#xff08;一&#xff09;倒排索引的本質與構建流程 倒排索引&#xff08;Inverted Index&#xff09;是搜索引擎實現快速檢索的核心數據結構&#xff0c;與傳統數據庫的正向索引&#xff08;文檔→關鍵詞&#xff0…

深度學習入門:從零搭建你的第一個神經網絡

深度學習入門&#xff1a;從零搭建你的第一個神經網絡 系統化學習人工智能網站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目錄 深度學習入門&#xff1a;從零搭建你的第一個神經網絡摘要引言第一章&#xff1a;神經網絡基礎原理1.1 神經元…

Hadoop 3.x 偽分布式 8088端口無法訪問問題處理

【Hadoop】YARN ResourceManager 啟動后 8088 端口無法訪問問題排查與解決(偽分布式啟動Hadoop) 在配置和啟動 Hadoop YARN 模塊時&#xff0c;發現雖然 ResourceManager 正常啟動&#xff0c;JPS 進程中也顯示無誤&#xff0c;但通過瀏覽器訪問 http://主機IP:8088 時卻無法打…

docker B站學習

鏡像是一個只讀的模板&#xff0c;用來創建容器 容器是docker的運行實例&#xff0c;提供了獨立可移植的環境 https://www.bilibili.com/video/BV11L411g7U1?spm_id_from333.788.videopod.episodes&vd_sourcee60c804914459274157197c4388a4d2f&p3 目錄掛載 尚硅谷doc…

鴻蒙OSUniApp微服務架構實踐:從設計到鴻蒙部署#三方框架 #Uniapp

UniApp微服務架構實踐&#xff1a;從設計到鴻蒙部署 引言 在最近的一個大型跨平臺項目中&#xff0c;我們面臨著一個有趣的挑戰&#xff1a;如何在UniApp框架下構建一個可擴展的微服務架構&#xff0c;并確保其在包括鴻蒙在內的多個操作系統上流暢運行。本文將分享我們的實踐…

Freemarker快速入門

Freemarker概述 FreeMarker 是一款 模板引擎&#xff1a; 即一種基于模板和要改變的數據&#xff0c; 并用來生成輸出文本(HTML網頁&#xff0c;電子郵件&#xff0c;配置文件&#xff0c;源代碼等)的通用工具。 它不是面向最終用戶的&#xff0c;而是一個Java類庫&#xff0c…

操作系統:生態思政

操作系統&#xff1a;生態思政 操作系統&#xff08;OS&#xff09;作為數字世界的基石&#xff0c;其意義遠超單純的技術平臺。它構建了一個包含開發者、用戶、硬件廠商在內的復雜生態系統&#xff0c;其設計理念、運行規則與生態治理模式&#xff0c;無不深刻映射著特定的價…

二進制安全-OpenWrt-uBus

1 需求 需求&#xff1a;ubus list 需求&#xff1a;ubus -v list 需求&#xff1a;ubus -v list zwrt_router.api 2 接口 rootOpenWrt:/# ubus Usage: ubus [<options>] <command> [arguments...] Options:-s <socket>: Set the unix domain …

Rust 學習筆記:自定義構建和發布配置

Rust 學習筆記&#xff1a;自定義構建和發布配置 Rust 學習筆記&#xff1a;自定義構建和發布配置發布配置文件自定義 profile 的選項 Rust 學習筆記&#xff1a;自定義構建和發布配置 發布配置文件 在 Rust 中&#xff0c;發布配置文件是預定義的和可定制的概要文件&#xf…

優化 Transformer 模型:基于知識蒸餾、量化技術及 ONNX

Transformer 模型非常強大&#xff0c;但往往太大太慢&#xff0c;不適合實時應用。為了解決這個問題&#xff0c;我們來看看三種關鍵的優化技術&#xff1a;知識蒸餾、量化和ONNX 圖優化。這些技術可以顯著減少推理時間和內存使用。 為了說明每種技術的利弊&#xff0c;我們以…

Vue3中Axios的使用-附完整代碼

前言 首先介紹一下什么是axios Axios 是一個基于 promise 網絡請求庫&#xff0c;作用于node.js 和瀏覽器中。 它是 isomorphic 的(即同一套代碼可以運行在瀏覽器和node.js中)。在服務端它使用原生 node.js http 模塊, 而在客戶端 (瀏覽端) 則使用 XMLHttpRequests 官方網站…

@Pushgateway自定義腳本推送數據

文章目錄 Pushgateway 自定義腳本推送數據1. 目的2. 適用范圍3. 前提條件4. 操作流程4.1 確定指標類型和格式4.2 編寫推送腳本方法一:使用 curl 命令行推送方法二:使用 Python 腳本推送方法三:使用 Python 客戶端庫推送4.3 設置定時任務4.4 驗證數據5. 高級配置5.1 使用基本…

Git 使用規范指南

Learn Git Branching 1Git 基礎使用流程 1.1初始化與克隆 # 初始化本地倉庫 git init# 克隆遠程倉庫 git clone <repo_url> 一般拉取代碼&#xff0c;直接在文件夾界面打開bash&#xff0c;git clone就行了 1.2日常開發流程 1拉取最新代碼 git pull origin <branc…

設計模式——備忘錄設計模式(行為型)

摘要 備忘錄設計模式是一種行為型設計模式&#xff0c;用于在不破壞封裝性的前提下&#xff0c;捕獲對象的內部狀態并在需要時恢復。它包含三個關鍵角色&#xff1a;原發器&#xff08;Originator&#xff09;、備忘錄&#xff08;Memento&#xff09;和負責人&#xff08;Car…

動態規劃十大經典題型狀態轉移、模版等整理(包括leetcode、洛谷題號)

動態規劃十大經典題目整理 0-1 背包問題&#xff08;0-1 Knapsack Problem&#xff09; LeetCode題號&#xff1a;無直接對應洛谷OJ題號&#xff1a;P1048狀態轉移方程&#xff1a;dp[j] max(dp[j], dp[j - weight[i]] value[i])C代碼模板&#xff1a; int dp[capacity 1…

簡單transformer運用

通俗易懂解讀&#xff1a;hw04.py 文件內容與 Transformer 的應用 這個文件是一個 Python 腳本&#xff08;hw04.py&#xff09;&#xff0c;用于完成 NTU 2021 Spring 機器學習課程的 HW4 作業任務&#xff1a;揚聲器分類&#xff08;Speaker Classification&#xff09;。它…

redis的哨兵模式和Redis cluster

目錄 一. redis的主從復制 二. 哨兵模式 2.1 定義 2.2 作用 2.3 配置實例 三. Redis cluster 3.1 定義 3.2 作用 3.3 配置實例 1. 新建集群文件目錄 2. 準備可執行文件到每個文件夾 3. 開啟群集功能 4. 啟動redis節點 5. 查看是否啟動成功 6. 啟動集群 7. 測試…

簡述八大排序(Sort)

1.插入排序 1.1直接插入排序 給定一組數據&#xff0c;若數據只有一個肯定是有序的&#xff0c;我們將無序數據一個個插入到已有序的數據中。用i遍歷無序數據&#xff0c;j遍歷有序數據&#xff0c;找到合適插入位置&#xff0c;用tmp存放目標插入數據&#xff0c;將其與j對應…