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

Go語言基礎學習之指針詳解

 更新時間:2022年12月30日 14:25:36   作者:程序員祝融  
Go 語言中指針是很容易學習的,Go 語言中使用指針可以更簡單的執(zhí)行一些任務。所以本文就來和大家聊聊Go語言中指針的定義與使用,需要的可以參考一下

今天來說說 Go 語言基礎中的指針。

Go 語言中指針是很容易學習的,Go 語言中使用指針可以更簡單的執(zhí)行一些任務。

1. 什么是指針

Go 語言中,一個指針變量指向了一個值的內(nèi)存地址。和 C、C++ 中的指針不同,Go 語言中的指針不能進行計算和偏移操作。

Go 語言中的函數(shù)傳參都是值拷貝,當我們想要修改某個變量的時候,我們可以創(chuàng)建一個指向該變量地址的指針變量。傳遞數(shù)據(jù)使用指針,而無須拷貝數(shù)據(jù)。

Go 語言中的指針操作非常簡單,只有記住兩個符號就可以了。

  • &(取地址)
  • *(根據(jù)地址取值)
var ip *int /* 指向整型*/

畫個重點,我們想徹底搞明白指針,必須要掌握 3 個概念:

  • 指針地址
  • 指針類型
  • 指針取值

接下來我們從這 3 點大家闡述 Go 語言指針,方便大家掌握。

2. 指針地址 & 指針類型

Go 語言變量在運行時都會被指定一個內(nèi)存地址,即變量在內(nèi)存中的位置。Go 語言通常在使用時會在變量前放一個 & 代表對變量進行 “ 取地址 ” 操作。Go 語言常用的值類型 (string、int、array、struct、float、bool )都會有對應的指針類型。如:string、 int、*int64 等。

每個變量在運行時都擁有一個地址,這個地址代表變量在內(nèi)存中的位置。Go語言中使用&字符放在變量前面對變量進行“取地址”操作。 Go語言中的值類型(int、float、bool、string、array、struct)都有對應的指針類型,如:int、int64、*string等。

取變量指針的語法如下:

package main

import "fmt"

func main(){
        
    a := 10   /* 聲明實際變量 */
    ip := &a  /* 指針變量的存儲地址 */
    
    
    fmt.Printf("a 變量的地址是: %x\n", &a  )
    
    /* 指針變量的存儲地址 */
    fmt.Printf("ip 變量儲存的指針地址: %x\n", ip )
    
    /* 使用指針訪問值 */
    fmt.Printf("*ip 變量的值: %d\n", *ip )
}

運行結(jié)果:

a 變量的地址是: 0xc000010200

ip 變量儲存的指針地址: 0xc000010200

*ip 變量的值: 10

其中:

  • a: 代表被取地址的變量,類型為 int
  • ip: 用于接收地址的變量,ip 的類型就為 *int,稱做 int 的指針類型。*代表指針。

用圖來表示一下 ip := &a:

以上就是指針地址和指針類型。

3. 指針取值

對變量使用 &會獲取該變量的指針,對指針使用 * 會獲取到值,也就是 “指正取值”。舉個例子更好的理解一下:

package main

import "fmt"

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

控制臺輸出結(jié)果:

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

小結(jié)一下:

  • 指針變量的值是指針地址 (可以結(jié)合上圖更好的理解)
  • 對變量進行取地址 &操作,可以獲得這個變量的指針變量
  • 對指針變量進行取值 *操作,可以獲得指針變量指向的原變量的值

函數(shù)傳值:

package main

import "fmt"

func main() {
    
    x := 2
    mod1(x)
    fmt.Println(x) // 2
    
    mod2(&x)
    fmt.Println(x) // 1024
}

func mod1(x int) {
    x = 1024
}

func mod2(x *int) {
    *x = 1024
}

4. 空指針

當一個指針被定義后沒有分配到任何變量時,它的值為 nil。

nil 指針也稱為空指針。

nil在概念上和其它語言的 null、None、nil、NULL一樣,都指代零值或空值。

一個指針變量通??s寫為 ptr

舉個例子:

package main

import "fmt"

func main() {
   var  ptr *int
   fmt.Printf("ptr 的值為 : %x\n", ptr) // ptr 的值為 : 0
}

空指針判斷:

package main

import "fmt"

func main() {
    var ptr *string
    fmt.Println(ptr)
    fmt.Printf("ptr的值是%v\n", ptr)
    
    if ptr != nil {
        fmt.Println("非空")
    } 
    if ptr == nil {
        fmt.Println("空值")
    }
}

5. make

make 是用于初始化內(nèi)置的數(shù)據(jù)結(jié)構(gòu),比如 slicemap 和 channel。

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

舉個例子:

package main

import "fmt"

func main() {
    var user map[string]int
    user = make(map[string]int, 10)
    user["age"] = 18
    fmt.Println(user)

    /** 
        slice := make([]int, 0, 100)
        hash := make(map[int]bool, 10)
        ch := make(chan int, 5)
    **/
}

6. new

new 的作用是根據(jù)傳入的類型分配一片內(nèi)存空間并返回指向這片內(nèi)存空間的指針。

func new(Type) *Type

解釋一下:

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

舉個例子:

package main

import "fmt"

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
}

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

面試高頻題,這個要考,記一下。

  • make 和 new 都是用來做內(nèi)存分配
  • make 只用于 slice、map 、channel 的初始化,返回的還是這三個引用類型本身,因為這三種類型就是引用類型,所以就沒必要返回其指針了
  • new 用于類型的內(nèi)存分配,并且內(nèi)存對應的值為類型零值,返回的是指向類型的指針。

8. 問題

Q: 執(zhí)行下面的代碼會出現(xiàn)啥問題?

package main

import "fmt"

func main() {
    var a *int
    *a = 100
    fmt.Println(*a)

    var user map[string]int
    user["age"] = 18
    fmt.Println(user)
}

A: 會出現(xiàn) panic runtime error: invalid memory address or nil pointer dereference。出錯行數(shù)在第 7 行。

原因:在 Go 語言中我們使用引用類型的變量需要先申明、分配內(nèi)存空間,否則在賦值是會出錯。值類型的變量除外,因為其在申明時就分配了默認的內(nèi)存空間。這也是 new 和 make 的作用。

到此這篇關(guān)于Go語言基礎學習之指針詳解的文章就介紹到這了,更多相關(guān)Go語言指針內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang限流器time/rate設計與實現(xiàn)詳解

    Golang限流器time/rate設計與實現(xiàn)詳解

    在?Golang?庫中官方給我們提供了限流器的實現(xiàn)golang.org/x/time/rate,它是基于令牌桶算法(Token?Bucket)設計實現(xiàn)的,下面我們就來看看他的具體使用吧
    2024-03-03
  • 詳解Go語言如何實現(xiàn)類似Python中的with上下文管理器

    詳解Go語言如何實現(xiàn)類似Python中的with上下文管理器

    熟悉?Python?的同學應該知道?Python?中的上下文管理器非常好用,那么在?Go?中是否也能實現(xiàn)上下文管理器呢,下面小編就來和大家仔細講講吧
    2023-07-07
  • Go語言常見錯誤之誤用init函數(shù)實例解析

    Go語言常見錯誤之誤用init函數(shù)實例解析

    Go語言中的init函數(shù)為開發(fā)者提供了一種在程序正式運行前初始化包級變量的機制,然而,由于init函數(shù)的特殊性,不當?shù)厥褂盟赡芤鹨幌盗袉栴},本文將深入探討如何有效地使用init函數(shù),列舉常見誤用并提供相應的避免策略
    2024-01-01
  • golang與pgsql交互的實現(xiàn)

    golang與pgsql交互的實現(xiàn)

    本文主要介紹了golang與pgsql交互的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • 用gin開發(fā)的golang項目三種開發(fā)模式方式

    用gin開發(fā)的golang項目三種開發(fā)模式方式

    這篇文章主要介紹了用gin開發(fā)的golang項目三種開發(fā)模式方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Golang使用協(xié)程實現(xiàn)批量獲取數(shù)據(jù)

    Golang使用協(xié)程實現(xiàn)批量獲取數(shù)據(jù)

    服務端經(jīng)常需要返回一個列表,里面包含很多用戶數(shù)據(jù),常規(guī)做法當然是遍歷然后讀緩存。使用Go語言后,可以并發(fā)獲取,極大提升效率,本文就來聊聊具體的實現(xiàn)方法,希望對大家有所幫助
    2023-02-02
  • Go實現(xiàn)用戶每日限額的方法(例一天只能領(lǐng)三次福利)

    Go實現(xiàn)用戶每日限額的方法(例一天只能領(lǐng)三次福利)

    這篇文章主要介紹了Go實現(xiàn)用戶每日限額的方法(例一天只能領(lǐng)三次福利)
    2022-01-01
  • omitempty在go中的使用方式

    omitempty在go中的使用方式

    在Go語言編程中,`omitempty`標記用于JSON編解碼過程中控制字段是否被包含,當結(jié)構(gòu)體字段標記為`omitempty`且字段值為空時,該字段不會出現(xiàn)在生成的JSON中,有助于優(yōu)化JSON結(jié)構(gòu)和減小數(shù)據(jù)體積,通過具體示例解釋了`omitempty`的工作機制和實際效果
    2024-09-09
  • Go語言遍歷map實現(xiàn)(訪問map中的每一個鍵值對)

    Go語言遍歷map實現(xiàn)(訪問map中的每一個鍵值對)

    這篇文章主要介紹了Go語言遍歷map實現(xiàn)(訪問map中的每一個鍵值對),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • 一文詳解Golang?定時任務庫?gron?設計和原理

    一文詳解Golang?定時任務庫?gron?設計和原理

    這篇文章主要介紹了一文詳解Golang?定時任務庫?gron?設計和原理,gron是一個比較小巧、靈活的定時任務庫,可以執(zhí)行定時的、周期性的任務。gron提供簡潔的、并發(fā)安全的接口
    2022-08-08

最新評論