Go語言使用make進行內(nèi)存分配的代碼示例
make 函數(shù)的基本概念
語法與適用類型
make
函數(shù)的語法格式為 make(T, args)
,其中 T
代表要創(chuàng)建的類型,必須是切片、映射或通道這三種引用類型之一,args
是根據(jù)不同類型而定的參數(shù)。以下是三種類型使用 make
函數(shù)的基本形式:
- 切片:
make([]T, length, capacity)
,其中T
是切片元素的類型,length
是切片的初始長度,capacity
是切片的初始容量(可省略,默認與長度相同)。 - 映射:
make(map[K]V, initialCapacity)
,K
是鍵的類型,V
是值的類型,initialCapacity
是映射的初始容量(可省略)。 - 通道:
make(chan T, bufferSize)
,T
是通道中元素的類型,bufferSize
是通道的緩沖區(qū)大?。墒÷?,省略時為無緩沖通道)。
代碼示例
package main import "fmt" func main() { // 使用 make 創(chuàng)建切片 slice := make([]int, 3, 5) fmt.Printf("切片長度: %d, 容量: %d, 內(nèi)容: %v\n", len(slice), cap(slice), slice) // 使用 make 創(chuàng)建映射 m := make(map[string]int) m["apple"] = 1 m["banana"] = 2 fmt.Println("映射內(nèi)容:", m) // 使用 make 創(chuàng)建通道 ch := make(chan int, 2) ch <- 10 ch <- 20 fmt.Println("從通道接收:", <-ch) }
在上述代碼中,分別使用 make
函數(shù)創(chuàng)建了切片、映射和通道,并進行了簡單的操作。
切片的 make 分配
長度與容量的區(qū)別
在使用 make
創(chuàng)建切片時,長度和容量是兩個重要的概念。長度表示切片中當前元素的數(shù)量,而容量表示切片底層數(shù)組的大小。可以通過 len()
函數(shù)獲取切片的長度,通過 cap()
函數(shù)獲取切片的容量。
package main import "fmt" func main() { // 創(chuàng)建一個長度為 2,容量為 5 的切片 slice := make([]int, 2, 5) fmt.Printf("初始長度: %d, 初始容量: %d\n", len(slice), cap(slice)) // 向切片追加元素 slice = append(slice, 1, 2, 3) fmt.Printf("追加元素后長度: %d, 容量: %d, 內(nèi)容: %v\n", len(slice), cap(slice), slice) }
在這個示例中,初始創(chuàng)建的切片長度為 2,容量為 5。當使用 append
函數(shù)追加元素時,如果長度超過了容量,Go 語言會自動重新分配更大的底層數(shù)組。
項目場景:數(shù)據(jù)處理
在數(shù)據(jù)處理項目中,我們可能需要動態(tài)地處理一批數(shù)據(jù)。使用 make
創(chuàng)建切片可以預先分配一定的容量,減少內(nèi)存重新分配的次數(shù),提高性能。
package main import ( "fmt" ) func processData() []int { // 預先分配容量為 100 的切片 data := make([]int, 0, 100) for i := 0; i < 100; i++ { data = append(data, i) } return data } func main() { result := processData() fmt.Println("處理后的數(shù)據(jù):", result) }
映射的 make 分配
初始容量的作用
在使用 make
創(chuàng)建映射時,指定初始容量可以提高映射的性能。如果預先知道映射可能存儲的元素數(shù)量,指定合適的初始容量可以減少哈希表擴容的次數(shù)。
package main import "fmt" func main() { // 創(chuàng)建一個初始容量為 10 的映射 m := make(map[string]int, 10) for i := 0; i < 10; i++ { key := fmt.Sprintf("key%d", i) m[key] = i } fmt.Println("映射內(nèi)容:", m) }
項目場景:緩存系統(tǒng)
在緩存系統(tǒng)中,映射可以用于存儲緩存數(shù)據(jù)。使用 make
創(chuàng)建映射并指定合適的初始容量,可以提高緩存系統(tǒng)的性能。
package main import ( "fmt" ) type Cache struct { data map[string]interface{} } func NewCache(capacity int) *Cache { return &Cache{ data: make(map[string]interface{}, capacity), } } func (c *Cache) Set(key string, value interface{}) { c.data[key] = value } func (c *Cache) Get(key string) (interface{}, bool) { val, exists := c.data[key] return val, exists } func main() { cache := NewCache(20) cache.Set("item1", 100) val, exists := cache.Get("item1") if exists { fmt.Println("緩存中獲取的值:", val) } }
通道的 make 分配
有緩沖通道與無緩沖通道
使用 make
創(chuàng)建通道時,可以指定緩沖區(qū)大小。如果不指定緩沖區(qū)大小,創(chuàng)建的是無緩沖通道,發(fā)送和接收操作會阻塞;如果指定了緩沖區(qū)大小,創(chuàng)建的是有緩沖通道,只有當緩沖區(qū)滿時發(fā)送操作才會阻塞,只有當緩沖區(qū)為空時接收操作才會阻塞。
package main import "fmt" func main() { // 創(chuàng)建無緩沖通道 ch1 := make(chan int) go func() { ch1 <- 10 fmt.Println("數(shù)據(jù)已發(fā)送到無緩沖通道") }() fmt.Println("從無緩沖通道接收:", <-ch1) // 創(chuàng)建有緩沖通道 ch2 := make(chan int, 2) ch2 <- 20 ch2 <- 30 fmt.Println("從有緩沖通道接收:", <-ch2) }
項目場景:并發(fā)任務(wù)處理
在并發(fā)任務(wù)處理中,通道可以用于協(xié)程之間的通信。使用 make
創(chuàng)建合適的通道可以協(xié)調(diào)不同協(xié)程的工作。
package main import ( "fmt" ) func worker(id int, jobs <-chan int, results chan<- int) { for j := range jobs { fmt.Printf("Worker %d 開始處理任務(wù) %d\n", id, j) results <- j * 2 } } func main() { const numJobs = 5 jobs := make(chan int, numJobs) results := make(chan int, numJobs) // 啟動 3 個工作協(xié)程 for w := 1; w <= 3; w++ { go worker(w, jobs, results) } // 發(fā)送任務(wù) for j := 1; j <= numJobs; j++ { jobs <- j } close(jobs) // 收集結(jié)果 for a := 1; a <= numJobs; a++ { <-results } close(results) }
總結(jié)
make 函數(shù)在 Go 語言中是為切片、映射和通道進行內(nèi)存分配和初始化的重要工具。通過合理使用 make 函數(shù),可以根據(jù)不同的需求為這些引用類型分配合適的內(nèi)存,提高程序的性能和效率。在實際項目中,無論是數(shù)據(jù)處理、緩存系統(tǒng)還是并發(fā)任務(wù)處理,make 函數(shù)都發(fā)揮著關(guān)鍵作用。開發(fā)者需要深入理解 make 函數(shù)的使用方法和不同類型的特點,根據(jù)具體的場景靈活運用。
以上就是Go語言使用make進行內(nèi)存分配的代碼示例的詳細內(nèi)容,更多關(guān)于Go make內(nèi)存分配的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
go-zero創(chuàng)建RESTful API 服務(wù)的方法
文章介紹了如何使用go-zero框架和goctl工具快速創(chuàng)建RESTfulAPI服務(wù),通過定義.api文件并使用goctl命令,可以自動生成項目結(jié)構(gòu)、路由、請求和響應模型以及處理邏輯,感興趣的朋友一起看看吧2024-11-11Golang實現(xiàn)自己的Redis(有序集合跳表)實例探究
這篇文章主要為大家介紹了Golang實現(xiàn)自己的Redis(有序集合跳表)實例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01GoLang?socket網(wǎng)絡(luò)編程傳輸數(shù)據(jù)包時進行長度校驗的方法
在GoLang?socket網(wǎng)絡(luò)編程中,為了確保數(shù)據(jù)交互的穩(wěn)定性和安全性,通常會通過傳輸數(shù)據(jù)的長度進行校驗,發(fā)送端首先發(fā)送數(shù)據(jù)長度,然后發(fā)送數(shù)據(jù)本體,接收端則根據(jù)接收到的數(shù)據(jù)長度和數(shù)據(jù)本體進行比較,以此來確認數(shù)據(jù)是否傳輸成功2024-11-11Windows+Linux系統(tǒng)下Go語言環(huán)境安裝配置過程
Go 語言被設(shè)計成一門應用于搭載 Web 服務(wù)器,存儲集群或類似用途的巨型中央服務(wù)器的系統(tǒng)編程語言。這篇文章主要介紹了Windows+Linux系統(tǒng)下Go語言環(huán)境搭建配置過程,針對每種系統(tǒng)給大家講解的非常詳細,需要的朋友可以參考下2021-06-06