Go變量指針的實現(xiàn)示例
更新時間:2025年09月26日 09:19:02 作者:Jayden_念舊
Go指針存儲變量地址,用于修改變量、避免拷貝、動態(tài)分配,本文就來詳細的介紹一下Go變量指針的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
在Go語言中,指針是一個存儲變量內(nèi)存地址的變量。通過指針,可以間接訪問和操作原始數(shù)據(jù)。從而提高程序的效率,特別是在處理復雜數(shù)據(jù)結構或需要共享數(shù)據(jù)時。
| 概念 | 說明 |
|---|---|
| 指針聲明 | var p *int |
| 取地址 | &a → 獲取 a 的地址 |
| 解引用 | *p → 訪問 p 指向的值 |
| 零值 | nil |
| 主要用途 | 修改變量、避免拷貝、動態(tài)分配 |
1.指針的本質
- 指針是一種特殊變量,其值是另一個變量的內(nèi)存地址。
- 通過指針可以間接訪問或修改原始變量的值。
2.聲明指針
語法:var ptr *Type
var a int = 10 var ptr *int // 聲明一個指向 int 類型的指針 ptr = &a // 將 a 的內(nèi)存地址賦值給 ptr
3.關鍵操作符
&(取地址符):獲取變量的內(nèi)存地址。
ptr = &a // ptr 現(xiàn)在存儲 a 的地址
*(解引用符):訪問指針指向的原始值。
fmt.Println(*ptr) // 輸出 10(通過 ptr 訪問 a 的值) *ptr = 20 // 修改 a 的值為 20
4.指針的零值
- 未初始化的指針值為
nil(表示無指向)。
var ptr *int // 初始值為 nil
5.指針的用途
- 修改函數(shù)外部的變量:
func modify(val *int) {
*val = 100
}
func main() {
x := 10
modify(&x) // x 被修改為 100
}- 避免大對象拷貝:傳遞結構體指針而非整個結構體,減少內(nèi)存開銷。
type Data struct { /* 大結構體 */ }
func process(d *Data) { /* 操作 d */ }- 動態(tài)內(nèi)存分配:與
new或復合字面量一起使用。
p := new(int) // 分配內(nèi)存,返回指針 *p = 42
6.指針示例
package main
import (
"fmt"
)
type Person struct {
Name string
Age int
Address string
Salary float64
}
func NewPerson(name string, age int, address string, salary float64) *Person {
return &Person{Name: name, Age: age, Address: address, Salary: salary}
}
func main() {
// 創(chuàng)建Person實例
p := NewPerson("張三", 30, "北京市海淀區(qū)", 15000.50)
// 訪問字段
fmt.Println(p.Name) // 輸出:張三
fmt.Println(p.Salary) // 輸出:15000.5
// 修改字段值
p.Age = 31
p.Salary = 16000.00
}為什么使用創(chuàng)建結構體指針:
1.內(nèi)存效率優(yōu)化
// 值類型返回(產(chǎn)生完整結構體拷貝)
func NewPerson() Person {
return Person{...}
}
// 指針類型返回(僅傳遞內(nèi)存地址)
func NewPerson() *Person {
return &Person{...}
}- 結構體大小:當結構體包含多個字段(特別是包含大數(shù)組等)時,指針傳遞(通常 8 字節(jié))比值拷貝更高效
- 調用鏈損耗:在方法調用鏈中多次傳遞時,指針傳遞始終維持固定內(nèi)存開銷
2. 可變性控制
p := NewPerson("李四", 28, "上海", 25000)
p.Age = 29 // 直接修改原結構體
// 值類型接收者方法示例(無法修改原結構體)
func (p Person) SetAge(age int) {
p.Age = age // 僅修改副本
}
// 指針類型接收者方法示例
func (p *Person) RealSetAge(age int) {
p.Age = age // 修改原結構體
}- 指針接收者:通過返回指針,后續(xù)可以方便地定義指針接收者方法
- 狀態(tài)一致性:確保所有方法操作都作用于同一個內(nèi)存對象
3. 零值有效性
// 錯誤處理擴展性
func NewPerson(age int) (*Person, error) {
if age < 0 {
return nil, errors.New("invalid age")
}
return &Person{Age: age}, nil
}- nil 語義:當構造函數(shù)需要實現(xiàn)錯誤處理時,指針類型可以直接返回 nil
- 可選對象:調用方可通過
if p != nil判斷對象是否有效
7.注意?。。。。。?!
- 空指針(nil):解引用
nil指針會導致運行時 panic。 - 指針算術:Go 不支持指針算術(如
ptr++),除非使用unsafe包(不推薦)。 - 值傳遞 vs 指針傳遞:函數(shù)參數(shù)默認值傳遞,需用指針實現(xiàn)引用傳遞。
擴展:使用指針修改原始變量和通過函數(shù)修改的區(qū)別是什么
原理差異
- 指針修改:在 Go 里,字符串是不可變類型,若要通過指針修改字符串,實際上修改的是存儲字符串的字節(jié)切片。因為字符串底層由字節(jié)數(shù)組構成,借助指針操作可改變字節(jié)切片內(nèi)容,再轉換回字符串,從而更新原始變量。
strings.Builder修改:strings.Builder內(nèi)部維護一個字節(jié)切片,提供方法將字符串追加到該切片。當調用String方法時,會把內(nèi)部字節(jié)切片轉換為字符串返回。這種方式不會直接修改原始字符串,而是生成新字符串后重新賦值給原始變量。
代碼實現(xiàn)差異
指針修改示例
package main
import (
"fmt"
)
func modifyString(s *string) {
bytes := []byte(*s)
bytes = append(bytes, ' ', 'a', 'b', 'c')
*s = string(bytes)
}
func main() {
str := "this is a string"
fmt.Println(&str)
modifyString(&str)
fmt.Println(str)
}strings.Builder修改示例
package main
import (
"fmt"
"strings"
)
func main() {
str := "this is a string"
fmt.Println(&str)
// 創(chuàng)建一個 strings.Builder 實例
var builder strings.Builder
// 將原始字符串寫入 Builder
builder.WriteString(str)
// 在末尾添加 abc
builder.WriteString(" abc")
// 獲取最終的字符串
str = builder.String()
fmt.Println(str)
}性能差異
- 指針修改:每次修改都要將字符串轉換為字節(jié)切片,修改后再轉換回字符串,頻繁轉換會帶來額外內(nèi)存分配和復制開銷,性能欠佳。
strings.Builder修改:內(nèi)部維護字節(jié)切片,可動態(tài)擴容,減少內(nèi)存分配次數(shù),拼接字符串時性能更優(yōu),尤其在處理大量字符串拼接時優(yōu)勢明顯。
使用場景差異
- 指針修改:適用于需要直接操作原始變量內(nèi)存地址,且修改操作較少的場景,或者希望通過函數(shù)修改外部變量的場景。
strings.Builder修改:適合需要頻繁進行字符串拼接的場景,能有效提升性能。
到此這篇關于Go變量指針的實現(xiàn)示例的文章就介紹到這了,更多相關Go變量指針內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:
相關文章
使用Go和Gorm實現(xiàn)讀取SQLCipher加密數(shù)據(jù)庫
本文檔主要描述通過Go和Gorm實現(xiàn)生成和讀取SQLCipher加密數(shù)據(jù)庫以及其中踩的一些坑,文章通過代碼示例講解的非常詳細, 對大家的學習或工作有一定的幫助,需要的朋友可以參考下2024-06-06
go語言實現(xiàn)將重要數(shù)據(jù)寫入圖片中
本文給大家分享的是go語言實現(xiàn)將數(shù)據(jù)的二進制形式寫入圖像紅色通道數(shù)據(jù)二進制的低位,從而實現(xiàn)將重要數(shù)據(jù)隱藏,有需要的小伙伴參考下吧。2015-03-03

