Go語言學習查缺補漏ing Day5

恆生LIGHT雲社群發表於2021-12-08

作者:ReganYue

來源: 恆生LIGHT雲社群

Go語言學習查缺補漏ing Day5

一、將切片當可變引數傳遞的一個問題

我們來看一段程式碼:

package main


import "fmt"

func Myfunc(num ...int) {
  num[0] = 2
  total := 0
  for _, i := range num {
      total += i
  }
  num[1] = total
}
func Sum(num ...int) {

  total := 0
  for _, i := range num {
      total += i
  }
  num[1] = total
}
func main() {
  i := []int{1, 2, 3}
  Myfunc(i...)
  fmt.Println(i)
  Sum(i...)
  fmt.Println(i)
}

這段程式碼的執行結果是:

[2 7 3]

[2 12 3]

是不是很奇怪為什麼切片內的值改變了?其實我們將切片作為函式引數傳遞給函式是進行的值傳遞,所以我們傳遞給函式的引數其實是下面這個slice的值複製。

type slice struct{

  value *int 
  length uint 
  capacity uint 
}

但是,這個slice結構體內的value是一個指標,所以這個slice就算進行了複製,它和它的複製值都是同一個value,指向同一塊區域。

所以上面的程式碼,我們可以在Myfunc和Sum函式中對main函式內的i切片進行操作。

但是,當我們對num切片進行擴容操作時,複製值的value指向的地址就可能會發生變化。

比如我們進行下面的操作:

func Sum(num ...int) {

  num[0] = 8
  total := 0
  for _, i := range num {
      total += i
  }
  num = append(num, total)
  num[1] = total
}

執行結果是:

[2 7 3]

[8 7 3]

這就側面描述了slice的擴容演算法。

另外說到可變引數,我們還需要注意幾點,這裡我們應該瞭解可變長引數應該是函式頭中最後一個引數!!!

有些人會疑惑,不是說可變引數嗎?怎麼傳入了一個切片?其實可變引數的底層就是用切片實現的,它是將傳入的一個或多個引數轉換為一個切片。

二、Go中不允許不同型別的資料進行運算

我們都知道,Go中具有極其嚴格的靜態型別限制,只有相同型別的資料才能進行運算,那麼如何解決這個問題呢?

第一點自然是強制型別轉換。比如:

func main() {

  var (
      i int     = 3
      j float32 = 3.1
  )
  fmt.Println(float32(i) + j)
}

這個程式執行就不會編譯錯誤,執行結果是6.1。

還有一種方法,不過適用場景比較單一。就是定義無型別常量。比如:

package main


import (
  "fmt"
)

func main() {
  const i = 1
  const j = 2.1

  fmt.Println(i + j)
}

執行就不會報錯,執行結果是3.1.

三、不同長度陣列能否進行比較

看一看下面這段程式碼:

package main


import (
  "fmt"
)

func main() {
  a := [2]int{1, 2}
  b := [3]int{1, 2}
  if a == b {
      fmt.Println("equal")
  } else {
      fmt.Println("not equal")
  }
}

你覺得他們相不相等?

哈哈哈哈

其實都不能透過編譯,因為陣列的長度是陣列的一部分,所以兩個陣列不是相同的型別,所以他們無法進行比較,故會報錯:

invalid operation: a == b (mismatched types [2]int and [3]int)

四、關於map的一點需要注意的地方

我們先來看看這段程式碼:

package main


import (
"fmt"
)

func main() {
Map := make(map[string]int)
delete(Map, "map")
fmt.Println(Map["map"])
}

Map是空的,你覺得會報錯嗎?如果不報錯,會輸出什麼?

答案是不會報錯,會輸出0.

是不是想對了?下面來解釋一下:

Go設計的就是刪除map中不存在的鍵值對時不會報錯,另外獲取map中並不存在的鍵值對時,獲取到的是值型別的零值。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70001864/viewspace-2846498/,如需轉載,請註明出處,否則將追究法律責任。

相關文章