Go中unsafe.Pointer類型的使用小結
更新時間:2026年02月05日 09:39:49 作者:Kevin666
unsafe.Pointer?是?Go?語言標準庫?unsafe?包中的一個特殊類型,用于在不同類型的指針之間進行?無類型轉換,允許你繞過?Go?的類型系統(tǒng)進行底層操作,感興趣的可以了解一下
unsafe.Pointer 是 Go 語言標準庫 unsafe 包中的一個特殊類型,用于在不同類型的指針之間進行 無類型轉換,允許你繞過 Go 的類型系統(tǒng)進行底層操作,屬于“不安全”的操作。
?? 使用場景
- 類型不兼容的指針轉換(例如從 *int 轉為 *float64)
- 與 uintptr 配合操作底層內存地址
- 修改只讀字段(例如字符串的只讀字節(jié))
- 實現類似 C 的結構體偏移訪問
和普通指針的區(qū)別
unsafe.Pointer 和普通的 &T 指針(即 *T)在 Go 中有本質上的區(qū)別
| 類型 | 說明 |
|---|---|
| *T | 是類型安全的指針,指向類型 T 的數據。編譯器知道它的類型信息,能自動進行內存對齊、類型檢查等。 |
| unsafe.Pointer | 是一種通用的無類型指針,可以轉換為任意類型的指針或從任意類型的指針轉換過來。編譯器不檢查其指向的類型和用法。 |
? 示例 1:不同類型指針轉換
package main
import (
"fmt"
"unsafe"
)
func main() {
var x int = 100
// 將 *int 轉換為 *float64(不安全!僅用于演示)
p := unsafe.Pointer(&x)
f := (*float64)(p) // 假裝 x 是 float64
fmt.Println(*f) // 輸出不確定,因為解釋方式不對
}
?這是錯誤用法,僅作為類型轉換的演示。實際運行會出現亂碼或未定義行為。
? 示例 2:uintptr與unsafe.Pointer配合做地址偏移(字段偏移)
package main
import (
"fmt"
"unsafe"
)
type Person struct {
age int
score float64
}
func main() {
p := Person{age: 25, score: 98.5}
// 獲取結構體首地址
ptr := unsafe.Pointer(&p)
// 偏移到第二個字段(score)
scorePtr := (*float64)(unsafe.Pointer(uintptr(ptr) + unsafe.Offsetof(p.score)))
fmt.Println(*scorePtr) // 輸出:98.5
}
? 示例 3:修改字符串的只讀內容(危險行為)
package main
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
s := "hello"
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
// 強轉為字節(jié)數組指針修改內容
b := (*[5]byte)(unsafe.Pointer(sh.Data))
b[0] = 'H'
fmt.Println(s) // 輸出 "Hello"
}
?這是標準庫明確禁止的行為,僅作教學展示。在某些平臺上可能 crash!
? 小結
| 場景 | 是否安全 | 推薦使用 |
|---|---|---|
| 類型間轉換(*T1 ? *T2) | ? | ? |
| 與 uintptr 搭配偏移操作 | ? | ? |
| 直接操作底層數據(如字符串修改) | ? | ? |
到此這篇關于Go中unsafe.Pointer類型的使用小結的文章就介紹到這了,更多相關Go unsafe.Pointer類型內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
使用Golang的singleflight防止緩存擊穿的方法
這篇文章主要介紹了使用Golang的singleflight防止緩存擊穿的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-04-04

