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
}
为什么这个代码
unsafe.Sizeof(*i)
会导致运行时panic 吗?
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
}
为什么这个代码
unsafe.Sizeof(*i)
会导致运行时panic 吗?
对
Alignof
、Offsetof
和Sizeof
的呼叫是类型uintptr
的compile-time constant expressions.
这些函数在编译时求值,在运行时不会发生实际的取消引用.
这是可能的,因为不需要指向的值,只需要有关其类型的信息,不需要取消引用.
它还记录在unsafe.Sizeof()
:
Sizeof的返回值是GO常量.
GO中的常量是编译时常量.
常量值由rune、integer、floating-point、imaginary或string字面值表示,标识符表示常量、constant expression、conversion,结果为常量,or the result value of some built-in functions such as 108 applied to any value、
cap
或len
应用于some expressions、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
在Go Playground号公路上试试这些.