網站首頁 編程語言 正文
今天來說說 Go 語言基礎中的指針。
Go 語言中指針是很容易學習的,Go 語言中使用指針可以更簡單的執行一些任務。
1. 什么是指針
Go 語言中,一個指針變量指向了一個值的內存地址。和 C、C++ 中的指針不同,Go 語言中的指針不能進行計算和偏移操作。
Go 語言中的函數傳參都是值拷貝,當我們想要修改某個變量的時候,我們可以創建一個指向該變量地址的指針變量。傳遞數據使用指針,而無須拷貝數據。
Go 語言中的指針操作非常簡單,只有記住兩個符號就可以了。
- &(取地址)
- *(根據地址取值)
var ip *int /* 指向整型*/
畫個重點,我們想徹底搞明白指針,必須要掌握 3 個概念:
- 指針地址
- 指針類型
- 指針取值
接下來我們從這 3 點大家闡述 Go 語言指針,方便大家掌握。
2. 指針地址 & 指針類型
Go 語言變量在運行時都會被指定一個內存地址,即變量在內存中的位置。Go 語言通常在使用時會在變量前放一個?&
?代表對變量進行 “ 取地址 ” 操作。Go 語言常用的值類型 (string、int、array、struct、float、bool )都會有對應的指針類型。如:string、?int、*int64 等。
每個變量在運行時都擁有一個地址,這個地址代表變量在內存中的位置。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 ) }
運行結果:
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 // 指針取值(根據指針去內存取值) 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
小結一下:
- 指針變量的值是指針地址 (可以結合上圖更好的理解)
- 對變量進行取地址?
&
操作,可以獲得這個變量的指針變量 - 對指針變量進行取值?
*
操作,可以獲得指針變量指向的原變量的值
函數傳值:
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
一樣,都指代零值或空值。
一個指針變量通常縮寫為?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
?是用于初始化內置的數據結構,比如?slice
、map
?和?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
?的作用是根據傳入的類型分配一片內存空間并返回指向這片內存空間的指針。
func new(Type) *Type
解釋一下:
- Type 表示類型,new 函數只接受一個參數,這個參數是一個類型
- *Type 表示類型指針,new 函數返回一個指向該類型內存地址的指針
舉個例子:
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 的區別
面試高頻題,這個要考,記一下。
- make 和 new 都是用來做內存分配
- make 只用于 slice、map 、channel 的初始化,返回的還是這三個引用類型本身,因為這三種類型就是引用類型,所以就沒必要返回其指針了
- new 用于類型的內存分配,并且內存對應的值為類型零值,返回的是指向類型的指針。
8. 問題
Q:?執行下面的代碼會出現啥問題?
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:?會出現?panic runtime error: invalid memory address or nil pointer dereference
。出錯行數在第 7 行。
原因:在 Go 語言中我們使用引用類型的變量需要先申明、分配內存空間,否則在賦值是會出錯。值類型的變量除外,因為其在申明時就分配了默認的內存空間。這也是 new 和 make 的作用。
原文鏈接:https://segmentfault.com/a/1190000043187142
相關推薦
- 2022-06-20 音視頻基本概念和FFmpeg的簡單入門教程詳解_相關技巧
- 2022-08-10 pandas.DataFrame.iloc的具體使用詳解_python
- 2023-11-21 高階函數HoF:用filter()方法編寫一個素數生成函數primes()
- 2021-11-28 linux手工配置ip地址詳細步驟_Linux
- 2022-06-29 tomcat下部署jenkins的實現方法_Tomcat
- 2022-05-18 python?安全地刪除列表元素的方法_python
- 2023-04-27 React中關于render()的用法及說明_React
- 2022-10-18 C/C++函數指針深入探究_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支