xia*_*gle 5 pointers runtime-error go
https://go.dev/play/p/X_BH4qGgXHJ
package main
import (
"fmt"
"unsafe"
)
func main() {
var i *int
fmt.Println(unsafe.Sizeof(*i)) // dereference of null pointer i
}
Run Code Online (Sandbox Code Playgroud)
为什么这段代码没有
unsafe.Sizeof(*i)
Run Code Online (Sandbox Code Playgroud)
导致运行时恐慌?
对
Alignof、Offsetof、 和 的调用Sizeof是类型的编译时常量表达式uintptr。
这些函数在编译时评估,运行时不会发生实际的取消引用。
这是可能的,因为不需要指向的值,只需要有关其类型的信息,这不需要取消引用。
它还记录在unsafe.Sizeof():
Sizeof 的返回值是一个 Go 常量。
Go 中的常量是编译时常量。
另请参阅规范:常量:
常量值由符文、整数、浮点、虚数或字符串文字、表示常量的标识符、常量表达式、结果为常量的转换或某些内置函数的结果值表示。函数例如
unsafe.Sizeof应用于任何值,cap或len应用于某些表达式,应用于复数常量和应用于数字常量real。imag
查看类似的示例(如果不传递它们,则会unsafe.Sizeof()在运行时出现恐慌或无限期阻塞,但它们工作得很好):
fmt.Println(unsafe.Sizeof(*(*int8)(nil))) // 1, no dereferencing
fmt.Println(unsafe.Sizeof([]int16{}[10])) // 2, no indexing
x := "hi"
fmt.Println(unsafe.Sizeof(x[10])) // 1, no indexing
fmt.Println(unsafe.Sizeof(map[interface{}]int{}[[]int{}])) // 8, no indexing
fmt.Println(unsafe.Sizeof((interface{})(nil).(int16))) // 2, no type assertion
i := 0
fmt.Println(unsafe.Sizeof(i / i)) // 8, no division by 0
i = -1
fmt.Println(unsafe.Sizeof(1 << i)) // 8, no negative shift count
fmt.Println(unsafe.Sizeof(make([]int, i))) // 24, no negative length
fmt.Println(unsafe.Sizeof((*[1]int)([]int{}))) // 8, no converting to bigger array
fmt.Println(unsafe.Sizeof((func() int32)(nil)())) // 4, no function call
fmt.Println(unsafe.Sizeof(<-(chan int64)(nil))) // 8, no receiving
var a, b interface{} = []int{}, []int{}
fmt.Println(unsafe.Sizeof(a == b)) // 1, no comparison
Run Code Online (Sandbox Code Playgroud)
在Go Playground上尝试这些。