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

深入理解Golang中指針的用途與技巧

 更新時間:2023年05月23日 15:07:26   作者:金刀大菜牙  
在 Go 語言中,指針是一種重要的概念,了解和正確使用指非常關(guān)鍵,因此本文小編就來和大家講講Golang 中指針的概念與用法,希望對大家有所幫助

在 Go 語言中,指針是一種重要的概念。了解和正確使用指針對于理解語言的底層機制、編寫高效的代碼以及處理復(fù)雜數(shù)據(jù)結(jié)構(gòu)都非常關(guān)鍵。本文將深入探討 Golang 中指針的概念、用法。

1. 指針的基本概念和語法

指針是一個存儲變量內(nèi)存地址的變量。它提供了直接訪問內(nèi)存中數(shù)據(jù)的能力,可以用于改變變量的值。在Go語言中,使用 * 表示指針類型,通過 & 操作符獲取變量的地址,通過 * 操作符解引用指針獲取指針指向的值。

在 Go 語言中,每個變量在運行時都具有一個地址,該地址表示變量在內(nèi)存中的位置。要對變量進行"取地址"操作,可以在變量前加上 & 字符。此外,Go 語言中的值類型(如 int、float、bool、string、array 和 struct)都有相應(yīng)的指針類型,分別為 *int、*float64、*bool、*string 等。

1.1 指針的聲明和初始化

在 Go 語言中,可以使用指針來引用任何類型的變量。指針的聲明和初始化可以通過如下語法完成:

 var p *int  // 聲明一個指向 int 類型的指針 p
 var str *string  // 聲明一個指向 string 類型的指針 str

初始化指針可以通過 new 函數(shù)來分配內(nèi)存并返回指針的地址:

 p := new(int)  // 分配一個 int 類型的內(nèi)存,并將指針 p 指向該內(nèi)存

示例代碼:

 package main
 ?
 import "fmt"
 ?
 func main() {
     var p *int
     var str *string
 ?
     fmt.Printf("p: %v, str: %v\n", p, str) // 輸出 p: <nil>, str: <nil>
 ?
     x := 10
     p = &x // 將指針p指向變量x的地址
 ?
     fmt.Printf("p: %v\n", p)   // 輸出 p: 0xc0000100e0
     fmt.Printf("*p: %d\n", *p) // 輸出 *p: 10
 ?
     str = new(string) // 分配一個string類型的內(nèi)存,并將指針str指向該內(nèi)存
 ?
     fmt.Printf("str: %v\n", str)   // 輸出 str: 0xc000010120
     fmt.Printf("*str: %s\n", *str) // 輸出 *str: ""
 ?
     *str = "Hello, Go!" // 通過指針修改字符串的值
 ?
     fmt.Printf("*str: %s\n", *str) // 輸出 *str: Hello, Go!
 }

1.2 獲取指針的地址和解引用

通過 & 操作符可以獲取變量的地址,例如:

x := 10
 p := &x  // 將指針 p 指向變量 x 的地址
 ?
 a := 10
 b := &a // 將指針 b 指向變量 a 的地址

我們來看一下 b := &a 的圖示:

使用 * 操作符可以解引用指針,獲取指針指向的值:

 fmt.Println(*p)  // 輸出指針 p 指向的值,即變量 x 的值

示例代碼:

func main() {
     //指針取值
     a := 10
     b := &a // 取變量a的地址,將指針保存到b中
     fmt.Printf("type of b:%T\n", b)
     c := *b // 指針取值(根據(jù)指針去內(nèi)存取值)
     fmt.Printf("type of c:%T\n", c)
     fmt.Printf("value of c:%v\n", c)
 }

輸出如下:

type of b:*int
type of c:int
value of c:10

取地址操作符 & 和取值操作符 * 是一對互補操作符,& 取出地址,* 根據(jù)地址取出地址指向的值。

1.3 指針作為函數(shù)參數(shù)

在 Go 語言中,函數(shù)的參數(shù)傳遞默認是值傳遞。如果想要在函數(shù)內(nèi)部修改外部變量的值,可以通過傳遞指針來實現(xiàn)。

示例代碼:

 package main
 ?
 import "fmt"
 ?
 func changeValue(ptr *int) {
     *ptr = 20 // 修改指針指向的值
 }
 ?
 func main() {
     x := 10
     changeValue(&x) // 傳遞x的地址給changeValue函數(shù)
     fmt.Println(x) // 輸出修改后的x的值,即20
 }

2. 指針的應(yīng)用場景

指針在 Go 語言中有著廣泛的應(yīng)用場景,下面將從幾個方面介紹指針的常見應(yīng)用。

2.1 傳遞大對象

在函數(shù)參數(shù)傳遞時,如果直接傳遞大對象的副本,會產(chǎn)生額外的內(nèi)存開銷。通過傳遞指針,可以避免復(fù)制整個對象,提高程序的性能。

示例代碼:

package main
 ?
 import "fmt"
 ?
 type BigObject struct {
     // 大對象的定義...
 }
 ?
 func processObject(obj *BigObject) {
     // 對大對象進行處理...
 }
 ?
 func main() {
     obj := BigObject{}
     processObject(&obj) // 傳遞大對象的指針
 }

2.2 修改函數(shù)外部變量

通過指針,函數(shù)可以修改函數(shù)外部的變量。這在需要修改外部變量的值時非常有用,特別是在處理復(fù)雜數(shù)據(jù)結(jié)構(gòu)或需要對全局狀態(tài)進行修改的情況下。

示例代碼:

package main
 ?
 import "fmt"
 ?
 func modifyValue(ptr *int) {
     *ptr = 30 // 修改指針指向的值
 }
 ?
 func main() {
     x := 10
     modifyValue(&x) // 傳遞x的地址給modifyValue函數(shù)
     fmt.Println(x) // 輸出修改后的x的值,即30
 }

2.3 動態(tài)分配內(nèi)存

指針的另一個重要應(yīng)用是動態(tài)分配內(nèi)存。通過 new 函數(shù)可以在堆上動態(tài)分配內(nèi)存,避免了在棧上分配固定大小的內(nèi)存空間的限制。這對于需要返回動態(tài)分配的數(shù)據(jù)或創(chuàng)建復(fù)雜數(shù)據(jù)結(jié)構(gòu)非常有用。

示例代碼:

 package main
 ?
 import "fmt"
 ?
 type ComplexStruct struct {
     // 復(fù)雜數(shù)據(jù)結(jié)構(gòu)的定義...
 }
 ?
 func createComplexStruct() *ComplexStruct {
     cs := new(ComplexStruct) // 動態(tài)分配內(nèi)存并返回指針
     // 初始化復(fù)雜數(shù)據(jù)結(jié)構(gòu)...
     return cs
 }
 ?
 func main() {
     obj := createComplexStruct()
     // 對動態(tài)分配的數(shù)據(jù)結(jié)構(gòu)進行操作...
 }

2.4 函數(shù)返回指針

在函數(shù)中返回指針可以將函數(shù)內(nèi)部創(chuàng)建的變量的地址傳遞給調(diào)用者。這樣做可以避免復(fù)制整個變量,并允許調(diào)用者直接訪問和修改函數(shù)內(nèi)部的數(shù)據(jù)。

示例代碼:

package main
 ?
 import "fmt"
 ?
 func createValue() *int {
     x := 10 // 在函數(shù)內(nèi)部創(chuàng)建變量
     return &x // 返回變量的地址
 }
 ?
 func main() {
     p := createValue()
     fmt.Println(*p) // 輸出通過指針訪問的函數(shù)內(nèi)部變量的值,即10
 }

3. new 和 make

我們先來看一個例子:

func main() {
     var a *int
     *a = 100
     fmt.Println(*a)
 ?
     var b map[string]int
     b["沙河娜扎"] = 100
     fmt.Println(b)
 }

執(zhí)行上面的代碼會引發(fā) panic,為什么呢?在 Go 語言中,對于引用類型的變量,在使用之前需要先進行聲明,并為其分配內(nèi)存空間,否則無法存儲值。而對于值類型的聲明,無需手動分配內(nèi)存空間,因為它們在聲明時已經(jīng)默認分配了內(nèi)存空間。為了分配內(nèi)存空間,我們可以使用 Go 語言中內(nèi)建的兩個函數(shù):new 和 make。這兩個函數(shù)具有不同的用途,new 主要用于分配值類型的內(nèi)存空間,而 make 主要用于分配引用類型(如 slice、map 和 channel)的內(nèi)存空間。

3.1 new

new 是一個內(nèi)置的函數(shù),它的函數(shù)簽名如下:

func new(Type) *Type

Type 表示類型,new 函數(shù)只接受一個參數(shù),這個參數(shù)是一個類型,*Type 表示類型指針,new 函數(shù)返回一個指向該類型內(nèi)存地址的指針。

示例代碼:

 func main() {
     a := new(int)
     b := new(bool)
     fmt.Printf("%T\n", a) // *int
     fmt.Printf("%T\n", b) // *bool
     fmt.Println(*a)       // 0
     fmt.Println(*b)       // false
 }

3.2 make

make 也是用于內(nèi)存分配的,區(qū)別于 new,它只用于 slice、map 以及 channel 的內(nèi)存創(chuàng)建,而且它返回的類型就是這三個類型本身,而不是他們的指針類型,因為這三種類型就是引用類型,所以就沒有必要返回他們的指針了。make 函數(shù)的函數(shù)簽名如下:

func make(t Type, size ...IntegerType) Type

make 函數(shù)是無可替代的,我們在使用 slice、map 以及 channel 的時候,都需要使用 make 進行初始化,然后才可以對它們進行操作。

示例代碼:

 func main() {
     var b map[string]int
     b = make(map[string]int, 10)
     b["沙河娜扎"] = 100
     fmt.Println(b)
 }

4. 總結(jié)

指針是 Go 語言中一種重要的概念,它提供了直接訪問內(nèi)存和修改變量值的能力。正確使用指針可以提高程序的性能、處理復(fù)雜數(shù)據(jù)結(jié)構(gòu)以及實現(xiàn)并發(fā)編程中的數(shù)據(jù)共享和同步。

在編寫代碼時,我們應(yīng)該充分理解指針的特性和使用注意事項,避免指針引起的錯誤和不確定性。合理使用指針將幫助我們編寫出高效、可靠且易于維護的 Go 語言程序。

到此這篇關(guān)于深入理解Golang中指針的用途與技巧的文章就介紹到這了,更多相關(guān)Golang指針內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用Go添加HTTPS的實現(xiàn)代碼示例

    使用Go添加HTTPS的實現(xiàn)代碼示例

    這篇文章主要介紹了使用Go添加HTTPS的實現(xiàn)代碼示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • golang值類型轉(zhuǎn)換成[]uint8類型的操作

    golang值類型轉(zhuǎn)換成[]uint8類型的操作

    這篇文章主要介紹了golang值類型轉(zhuǎn)換成[]uint8類型的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Golang?Mutex互斥鎖源碼分析

    Golang?Mutex互斥鎖源碼分析

    本篇文章,我們將一起來探究下Golang?Mutex底層是如何實現(xiàn)的,知其然,更要知其所以然。文中的示例代碼講解詳細,感興趣的可以了解一下
    2022-10-10
  • 使用Go語言實現(xiàn)微信公眾平臺

    使用Go語言實現(xiàn)微信公眾平臺

    這篇文章主要介紹了使用Go語言實現(xiàn)微信公眾平臺,雖然不是全部代碼,但是也是給我們提供了一個非常好的思路,需要的朋友可以參考下
    2015-01-01
  • golang字符串拼接實現(xiàn)方式和區(qū)別對比

    golang字符串拼接實現(xiàn)方式和區(qū)別對比

    本文介紹了Go語言中字符串拼接的多種方法及其優(yōu)缺點,推薦使用strings.Builder進行頻繁拼接以優(yōu)化內(nèi)存分配和性能,同時,還討論了通過sync.Pool優(yōu)化高頻創(chuàng)建的對象,以減少垃圾回收壓力,感興趣的朋友一起看看吧
    2025-02-02
  • golang 實現(xiàn)比特幣內(nèi)核之處理橢圓曲線中的天文數(shù)字

    golang 實現(xiàn)比特幣內(nèi)核之處理橢圓曲線中的天文數(shù)字

    比特幣密碼學(xué)中涉及到的大數(shù)運算超出常規(guī)整數(shù)范圍,需使用golang的big包進行處理,通過使用big.Int類型,能有效避免整數(shù)溢出,并保持邏輯正確性,測試展示了在不同質(zhì)數(shù)模下的運算結(jié)果,驗證了邏輯的準(zhǔn)確性,此外,探討了費馬小定理在有限字段除法運算中的應(yīng)用
    2024-11-11
  • go mod 安裝依賴 unkown revision問題的解決方案

    go mod 安裝依賴 unkown revision問題的解決方案

    這篇文章主要介紹了go mod 安裝依賴 unkown revision問題的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • GO語言操作Elasticsearch示例分享

    GO語言操作Elasticsearch示例分享

    這篇文章主要介紹了GO語言操作Elasticsearch示例分享的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • go build -tags構(gòu)建約束試驗示例解析

    go build -tags構(gòu)建約束試驗示例解析

    這篇文章主要為大家介紹了go build -tags構(gòu)建約束試驗示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • Go語言基礎(chǔ)數(shù)組用法及示例詳解

    Go語言基礎(chǔ)數(shù)組用法及示例詳解

    這篇文章主要為大家介紹了Go語言基礎(chǔ)Go語言數(shù)組的用法及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2021-11-11

最新評論