日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
深入理解Go中的new()和make()函數(shù)

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

站在用戶的角度思考問題,與客戶深入溝通,找到明溪網(wǎng)站設(shè)計與明溪網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:網(wǎng)站設(shè)計制作、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、國際域名空間、網(wǎng)頁空間、企業(yè)郵箱。業(yè)務(wù)覆蓋明溪地區(qū)。

一、引言

  • 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ù)類型進(jìn)行初始化。
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ù)類型進(jìn)行初始化。
package main

import "fmt"

func main() {
    // 使用 new() 創(chuàng)建一個結(jié)構(gòu)體的指針
    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)原理略有不同。

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

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

下面是 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 將指針轉(zhuǎn)換為 unsafe.Pointer 類型,再通過 uintptr 將 unsafe.Pointer 值轉(zhuǎn)換為 uintptr 類型,最后輸出指針的值。這個值就是我們所創(chuàng)建的變量的內(nèi)存地址。

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

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

下面是 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 將切片轉(zhuǎn)換為 reflect.Value 類型,再通過 Elem 方法獲取切片的元素,并通過 UnsafeAddr 方法獲取切片的底層數(shù)組的指針,最后通過 Len 方法獲取切片的長度。這樣,我們就可以獲得切片的底層數(shù)組的指針和長度。

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

總結(jié)

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


文章名稱:深入理解Go中的new()和make()函數(shù)
當(dāng)前路徑:http://m.5511xx.com/article/cdgicso.html