欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go中的new()和make()函數(shù)區(qū)別及底層原理詳解

 更新時間:2023年09月24日 15:26:20   作者:TimLiu  
這篇文章主要為大家介紹了Go中的new()和make()函數(shù)區(qū)別及底層原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

在 Go 語言中,new() 和 make() 是兩個常用的函數(shù),用于創(chuàng)建和初始化不同類型的變量。本文將深入探討 new() 和 make() 的區(qū)別、使用場景以及底層實現(xiàn)原理。

  • Go 中的 new() 和 make() 函數(shù)是用于創(chuàng)建和初始化變量的重要工具。
  • new() 用于創(chuàng)建指定類型的零值變量,并返回該變量的指針。
  • make() 用于創(chuàng)建并初始化引用類型的變量,如切片、映射和通道。

new() 函數(shù)

  • new() 函數(shù)的基本語法及用法。
  • new() 創(chuàng)建的變量是指定類型的零值,并返回該變量的指針。
  • new() 適用于創(chuàng)建引用類型以外的其他類型變量。
package main
import "fmt"
func main() {
    // 使用 new() 創(chuàng)建一個 int 類型的零值變量的指針
    numPtr := new(int)
    fmt.Println(*numPtr) // 輸出 0
}

make() 函數(shù)

  • make() 函數(shù)的基本語法及用法。
  • make() 用于創(chuàng)建并初始化引用類型的變量。
  • make() 適用于創(chuàng)建切片、映射和通道等引用類型的變量。
  • make() 創(chuàng)建的變量不是零值,而是根據(jù)類型進行初始化。
package main
import "fmt"
func main() {
    // 使用 make() 創(chuàng)建一個切片,并初始化長度為 3 的切片
    slice := make([]int, 3)
    fmt.Println(slice) // 輸出 [0 0 0]
}

new() 和 make() 的區(qū)別

  • new() 用于創(chuàng)建任意類型的變量,而 make() 僅用于創(chuàng)建引用類型的變量。
  • new() 返回的是指針,而 make() 返回的是初始化后的值。
  • new() 創(chuàng)建的變量是零值,make() 創(chuàng)建的變量是根據(jù)類型進行初始化。
package main
import "fmt"
func main() {
    // 使用 new() 創(chuàng)建一個結構體的指針
    personPtr := new(Person)
    personPtr.Name = "Alice"
    personPtr.Age = 30
    fmt.Println(personPtr) // 輸出 &{Alice 30}
    // 使用 make() 創(chuàng)建一個映射,并初始化鍵值對
    m := make(map[string]int)
    m["one"] = 1
    m["two"] = 2
    fmt.Println(m) // 輸出 map[one:1 two:2]
}
type Person struct {
    Name string
    Age  int
}

new() 和 make() 的底層實現(xiàn)原理

在 Go 語言中,new() 和 make() 的底層實現(xiàn)原理略有不同。

new() 的底層實現(xiàn)原理

  • new() 函數(shù)在底層使用了 Go 的 runtime.newobject 函數(shù)。
  • runtime.newobject 函數(shù)會分配一塊內存,大小為指定類型的大小,并將該內存清零。
  • 然后,runtime.newobject 函數(shù)會返回這塊內存的指針。

下面是 new() 函數(shù)的簡化版本的底層實現(xiàn)原理示例代碼:

package main
import (
    "fmt"
    "unsafe"
)
func main() {
    // 使用 new() 創(chuàng)建一個 int 類型的零值變量的指針
    numPtr := new(int)
    // 獲得指針的值
    ptrValue := uintptr(unsafe.Pointer(numPtr))
    // 輸出指針的值
    fmt.Println(ptrValue)
}

在上述示例代碼中,我們使用了 unsafe 包中的 Pointer 和 uintptr 類型來操作指針。我們首先使用 new(int) 創(chuàng)建一個 int 類型的零值變量的指針 numPtr,然后通過 unsafe.Pointer 將指針轉換為 unsafe.Pointer 類型,再通過 uintptr 將 unsafe.Pointer 值轉換為 uintptr 類型,最后輸出指針的值。這個值就是我們所創(chuàng)建的變量的內存地址。

make() 的底層實現(xiàn)原理

  • make() 函數(shù)在底層使用了 Go 的 runtime.makesliceruntime.makemap 和 runtime.makechan 函數(shù)。
  • runtime.makeslice 函數(shù)用于創(chuàng)建切片,它會分配一塊連續(xù)的內存空間,并返回切片結構體。
  • runtime.makemap 函數(shù)用于創(chuàng)建映射,它會分配一塊哈希表內存,并返回映射結構體。
  • runtime.makechan 函數(shù)用于創(chuàng)建通道,它會分配一塊通道內存,并返回通道結構體。

下面是 make() 函數(shù)的簡化版本的底層實現(xiàn)原理示例代碼:

package main
import (
    "fmt"
    "reflect"
    "unsafe"
)
func main() {
    // 使用 make() 創(chuàng)建一個切片,并初始化長度為 3 的切片
    slice := make([]int, 3)
    // 獲得切片的值和長度
    sliceValue := reflect.ValueOf(slice)
    sliceData := sliceValue.Elem().UnsafeAddr()
    sliceLen := sliceValue.Len()
    // 輸出切片的值和長度
    fmt.Println(sliceData, sliceLen)
}

在上述示例代碼中,我們使用了 reflect 包中的 Value、Elem 和 UnsafeAddr 方法來操作切片。我們首先使用 make([]int, 3) 創(chuàng)建一個長度為 3 的切片 slice,然后通過 reflect.ValueOf 將切片轉換為 reflect.Value 類型,再通過 Elem 方法獲取切片的元素,并通過 UnsafeAddr 方法獲取切片的底層數(shù)組的指針,最后通過 Len 方法獲取切片的長度。這樣,我們就可以獲得切片的底層數(shù)組的指針和長度。

請注意,上述示例代碼中使用了 reflect 和 unsafe 包,這是為了演示 make() 的底層實現(xiàn)原理而引入的,實際開發(fā)中并不需要經常使用這些包。

總結

通過深入了解 new() 和 make() 函數(shù)的區(qū)別、使用場景以及底層實現(xiàn)原理,讀者可以更好地理解和運用這兩個函數(shù),并完美解決掉面試官的問題,并在實際開發(fā)中做出準確的選擇。

以上就是Go中的new()和make()函數(shù)區(qū)別及底層原理詳解的詳細內容,更多關于Go new make函數(shù)的資料請關注腳本之家其它相關文章!

相關文章

  • Go中Context使用源碼解析

    Go中Context使用源碼解析

    這篇文章主要為大家介紹了Go中Context使用源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • 詳解Golang time包中的結構體time.Ticker

    詳解Golang time包中的結構體time.Ticker

    在日常開發(fā)過程中,會頻繁遇到對時間進行操作的場景,使用 Golang 中的 time 包可以很方便地實現(xiàn)對時間的相關操作,接下來的幾篇文章會詳細講解 time 包,本文講解一下 time 包中的結構體 time.Ticker,需要的朋友可以參考下
    2023-08-08
  • 一文搞懂如何實現(xiàn)Go 超時控制

    一文搞懂如何實現(xiàn)Go 超時控制

    這篇文章主要介紹了一文搞懂如何實現(xiàn)Go 超時控制,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • Golang實現(xiàn)驗證一個字符串是否為URL

    Golang實現(xiàn)驗證一個字符串是否為URL

    在實際開發(fā)過程中,有時候會遇到?URL?的校驗問題,Go?語言中有哪些方法去驗證一個字符串是否滿足?URL?格式呢?本文就來和大家詳細講講
    2023-04-04
  • golang強制類型轉換和類型斷言

    golang強制類型轉換和類型斷言

    這篇文章主要介紹了詳情介紹golang類型轉換問題,分別由介紹類型斷言和類型轉換,這兩者都是不同的概念,下面文章圍繞類型斷言和類型轉換的相關資料展開文章的詳細內容,需要的朋友可以參考以下
    2021-12-12
  • Golang線程池與協(xié)程池的使用

    Golang線程池與協(xié)程池的使用

    在Golang中,線程池和協(xié)程池是非常常見且重要的概念,它們可以提高應用程序的并發(fā)處理能力和性能,減少資源的浪費,本文就來介紹一下Golang線程池與協(xié)程池的使用,感興趣的可以了解一下
    2024-04-04
  • Go設計模式之單例模式圖文詳解

    Go設計模式之單例模式圖文詳解

    單例模式是一種創(chuàng)建型設計模式,讓你能夠保證一個類只有一個實例,并提供一個訪問該實例的全局節(jié)點,本文就通過圖文給大家介紹一下Go的單例模式,需要的朋友可以參考下
    2023-07-07
  • Go中如何使用set的方法示例

    Go中如何使用set的方法示例

    這篇文章主要介紹了Go中如何使用set的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • 基于Go語言實現(xiàn)高性能文件上傳下載系統(tǒng)

    基于Go語言實現(xiàn)高性能文件上傳下載系統(tǒng)

    在Web應用開發(fā)中,文件上傳下載是一個非常常見的需求,本文將介紹如何使用Go語言實現(xiàn)一個安全、高效的本地文件存儲系統(tǒng),感興趣的小伙伴可以了解下
    2025-03-03
  • Go并發(fā)之RWMutex的源碼解析詳解

    Go并發(fā)之RWMutex的源碼解析詳解

    RWMutex是一個支持并行讀串行寫的讀寫鎖。RWMutex具有寫操作優(yōu)先的特點,寫操作發(fā)生時,僅允許正在執(zhí)行的讀操作執(zhí)行,后續(xù)的讀操作都會被阻塞。本文就來從源碼解析一下RWMutex的使用
    2023-03-03

最新評論