非懂不可的Slice(二) 就要學習Go語言

2021-09-11 14:23:36 字數 2738 閱讀 6156

這一節,我們來討論更多關於slice的用法。

nil切片與空切片

nil切片

var s int

fmt.println(s == nil) // 輸出 true

fmt.println(len(s),cap(s)) // 輸出:0 0

複製**

上面這段**宣告了乙個nil切片s,其實,切片的零值就是nil。為什麼?通過上一節我們知道,因為切片就是乙個陣列的引用。切片的型別在初始化時已經確認,就是type,上面的**就宣告了int型別的nil切片snil切片的指向底層陣列的指標為nil

空切片如何宣告空切片?有兩種方式:

// 1、使用 make 建立空的整型切片

s := make(int, 0)

// 2、使用切片字面量建立空的整型切片

s := int{}

fmt.println(s) // 輸出:

fmt.println(len(s),cap(s)) // 輸出:0 0

複製**

通過上面**可以得出,與nil切片一樣,空切片的長度和容量也都是0,說明切片底層的陣列大小為0,是乙個空陣列(沒有分配任何的儲存空間)。

copy函式

go提供了內建函式copy,可以講乙個切片複製到另乙個切片。函式原型:

func

copy

(dst, src type)

int複製**

dst是目標切片,src是源切片,函式返回兩者長度的最小值。

var s1 int

s2 := int

s3 := int

s4 := int

// 1、

n1 := copy(s1, s2)

fmt.printf("n1=%d, s1=%v, s2=%v\n", n1, s1, s2)

fmt.println("s1 == nil", s1 == nil)

// 2、

n2 := copy(s2, s3)

fmt.printf("n2=%d, s2=%v, s3=%v\n", n2, s2, s3)

// 3、

n3 := copy(s3, s4)

fmt.printf("n3=%d, s3=%v, s4=%v\n", n3, s3, s4)

複製**

輸出:

n1=0, s1=, s2=[123]

s1 == nil

true

n2=3, s2=[4

56], s3=[456

7]n3=3, s3=[123

7], s4=[123]

複製**

var s1 int

s2 := int

fmt.println(s1) // 輸出:[1 2 3]

複製**

第二段**:由於s2的長度是3,s3的長度是4,所以執行copy操作只會從s3複製3個元素至s2copy只會複製,不會追加。 第三段**也是同樣的道理。

函式間傳遞切片

切片在函式間以值的方式傳遞。由於切片的尺寸很小(在 64 位架構的機器上,乙個切片需要 24 位元組的記憶體:指標字段、長度和容量欄位各需要 8 位元組),在函式間複製和傳遞切片成本也很低。切片發生複製時,底層陣列不會被複製,陣列大小也不會有影響。

func

main()

fmt.printf("%p\n", &s)

modify(s)

fmt.println(s)

}func

modify

(s int)

複製**

輸出:

0xc000086020

0xc000086040

[01023

45]複製**

我們可以看到,原切片位址和傳遞之後的切片的位址是不一樣的,說明發生了複製;在函式modify中修改了切片乙個值,原切片的值也隨之改變了,說明這兩個切片是共享底層陣列的。 在函式間傳遞切片非常高效,而且不需要傳遞指標和處理複雜的語法,只需要複製切片,按自己的業務修改資料,最後傳遞歸乙個新的切片副本即可,這也是為什麼函式間使用切片傳參,而不是陣列傳參的原因。

刪除切片中的元素

go沒有提供刪除切片元素的函式,然而,我們可以使用一些「黑科技」達到這樣的目的。

s := int

fmt.println(s)

複製**

輸出:

[124

56]複製**

通過這兩節詳解,相信你已經掌握了slice,建議大家要多多練習!

(全文完)

一看就懂的SwitchHosts

switchhosts 是乙個管理 切換多個 hosts 方案的工具。它是乙個免費開源軟體。日常開發工作中,我們可能經常需要切換各種 hosts 繫結,比如在本地開發時可能需要乙個開發環境的 hosts 繫結方案,發布到測試環境後又有乙個測試環境的 hosts 繫結方案,然後可能還有乙個預發布環境,...

看完就懂 C 的命名空間

命名空間是用來組織和重用 的編譯單元。namespace 名字空間 是為了解決命名衝突的問題而引入的概念。通過使用 namespace 就是 使用的範圍 你所使用的庫函式或變數就是在該名字空間中定義的,這樣一來就不會引起不必要的衝突了。c 標準程式庫中的所有識別符號都被定義於乙個名為std stan...

一看就懂的設計模式(二,工廠模式)

本文是在簡單工廠的基礎上進行編寫的,可以參考簡單工廠比較學習,看看都有哪些異同。namespace 工廠模式 先定義乙個基類 public class animal 子類繼承基類 public class dog animal public class pig animal 工廠類 public i...