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 吗?

推荐答案

Spec: Package unsafe:

AlignofOffsetofSizeof的呼叫是类型uintptrcompile-time constant expressions.

这些函数在编译时求值,在运行时不会发生实际的取消引用.

这是可能的,因为不需要指向的值,只需要有关其类型的信息,不需要取消引用.

它还记录在unsafe.Sizeof():

Sizeof的返回值是GO常量.

GO中的常量是编译时常量.

另见Spec: Constants:

常量值由runeintegerfloating-pointimaginarystring字面值表示,标识符表示常量、constant expressionconversion,结果为常量,or the result value of some built-in functions such as 108 applied to any valuecaplen应用于some expressionsrealimag,复数应用于数字常量.

请参见类似的示例(如果不将它们传递给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号公路上试试这些.

Go相关问答推荐

Golang测试容器,无法使网络正常工作

Golang应用程序:所请求的资源上不存在HTTP-Control-Allow-Origin标头

golang 的持久隐蔽服务

无法在32位计算机上运行Golang应用程序

如何确定泛型类型在运行时是否可比较?

Golang Gorm Fiber - 如何将定义为别名的名称发送到索引模板?

Gorm 在自定义字符串类型上返回 scanner 错误

将 firestoreinteger_value转换为整数

上传图片失败,出现错误dial tcp: lookup api.cloudinary.com: no such host

为什么不同的 Wireguard 私钥会产生相同的公钥?

枚举的 Golang 验证器自定义验证规则

Golang 构建多平台问题

如何使用 Go 获取 X11 中的窗口列表

Gorm 在保存/创建时序列化 struct

如何在 Golang 中使用具有相同名称或特定关键字的行或列重新排列/排序 CSV

将 Golang Gin 与 AWS Lambda 和无服务器与代理路径一起使用

无限期运行 Go routine (完成后重新启动)

Go 使用 struct 作为接口而不实现所有方法

防止在 Go 公用文件夹中列出目录

Go 1.18 泛型如何使用接口定义新的类型参数