## 一、Golang 可變參數
函數方法的參數,可以是任意多個,這種我們稱之為可以變參數,比如我們常用的fmt.Println()這類函數,可以接收一個可變的參數。
可以變參數,可以是任意多個。我們自己也可以定義可以變參數,可變參數的定義,在類型前加上省略號…即可。
~~~go
func main() {
print("1","2","3")
}
func print (a ...interface{}){
for _,v:=range a{
fmt.Print(v)
}
fmt.Println()
}
~~~
## 二、Slice和數組的對比
在 Go 中,與 C 數組變量隱式作為指針使用不同,Go 數組是值類型,賦值和函數傳參操作都會復制整個數組數據。假想每次傳參都用數組,那么每次數組都要被復制一遍。如果數組大小有 100萬,在64位機器上就需要花費大約 800W 字節,即 8MB 內存。這樣會消耗掉大量的內存。
于是乎有人想到,函數傳參用數組的指針。這樣更加高效的利用內存,性能也比之前的好。
不過傳指針會有一個弊端,萬一原數組的指針指向更改了,那么函數里面的指針指向都會跟著更改。
切片的優勢也就表現出來了。用切片傳數組參數,既可以達到節約內存的目的,也可以達到合理處理好共享內存的問題。打印結果第二行就是切片,切片的指針和原來數組的指針是不同的。
并非所有時候都適合用切片代替數組,因為切片底層數組可能會在堆上分配內存,而且小數組在棧上拷貝的消耗也未必比 make 消耗大。
## 三、Golang Slice的底層實現
切片是基于數組實現的,它的底層是數組,它自己本身非常小,可以理解為對底層數組的抽象。因為基于數組實現,所以它的底層的內存是連續分配的,效率非常高,還可以通過索引獲得數據,可以迭代以及垃圾回收優化。
切片本身并不是動態數組或者數組指針。它內部實現的數據結構通過指針引用底層數組,設定相關屬性將數據讀寫操作限定在指定的區域內。切片本身是一個只讀對象,其工作機制類似數組指針的一種封裝。
切片對象非常小,是因為它是只有3個字段的數據結構:
指向底層數組的指針
切片的長度
切片的容量
這3個字段,就是Go語言操作底層數組的元數據。
## 四、Golang Slice的擴容機制,有什么注意點?
Go 中切片擴容的策略是這樣的:
首先判斷,如果新申請容量大于2倍的舊容量,最終容量就是新申請的容量
否則判斷,如果舊切片的長度小于1024,則最終容量就是舊容量的兩倍
否則判斷,如果舊切片長度大于等于1024,則最終容量從舊容量開始循環增加原來的 1/4, 直到最終容量大于等于新申請的容量
[推薦1](https://blog.csdn.net/qq_35526714/article/details/114280569)
[推薦2](https://blog.csdn.net/weixin_46305978/article/details/123380358)
- 一、經典(一)
- 二、經典(二)
- 三、經典(三)
- 四、經典(四)
- 五、經典(五)
- 六、經典(六)
- 七、經典(七)
- 八、經典(八)
- 九、經典(九)
- 十、經典(十)
- 十一、經典(十一)
- 十二、經典(十二)
- 其他
- 1、知識點一
- 2、面試集
- 3、負載均衡原理
- 4、LVS相關了解
- 5、微服務架構
- 6、分布式鎖實現原理
- 7、Etcd怎么實現分布式鎖
- 8、Redis的數據結構有哪些,以及實現場景
- 9、Mysql高可用方案有哪些
- 10、Go語言的棧空間管理是怎么樣的
- 11、Goroutine和Channel的作用分別是什么
- 12、Go中的鎖有哪些?三種鎖,讀寫鎖,互斥鎖,還有map的安全的鎖?
- 13、怎么限制Goroutine的數量
- 14、Goroutine和線程的區別?
- 15、中間件原理