Golang中指针间接引用的层级在运行时是否有上限限制?

Golang中指针间接引用的层级在运行时是否有上限限制? 运行时可以有多少级指针间接引用?是否存在限制?

我隐约记得对于可以间接引用对象的次数存在某种限制,尽管我记不清是在什么背景下。有人能帮忙解答吗?

9 回复

更多关于Golang中指针间接引用的层级在运行时是否有上限限制?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


skillian:

真的很想看看你在写什么代码!

我也是,大部分时间我都在思考一些哲学问题。

我认为你可以拥有任意多层的指针,至少直到运行时安全检查不会因为内存不足而引发恐慌。当然,为了读取原始指向的值,你需要创建相同数量的变量,称为 abc 等……每个变量都引用前一个变量。这真的有用/清晰/符合惯用法吗?

大家好,

我隐约记得 Go 语言中有这样一个限制,显然它不是关于指针的。那么是关于什么的呢?可能是指向接口的指针,或者与接口转换相关。

去年(几个月前)这个论坛上有一个帖子讨论过这个问题。有一个限制是 2,但我不记得是针对什么了。

大家好,

在大多数编程语言中,运行时使用的指针间接寻址层级数量并没有硬性限制。然而,每一层间接寻址都会增加代码的复杂性,使用过多层级会使代码难以理解和维护。此外,使用过多的间接寻址层级可能导致性能问题,因为每一层都需要额外的内存访问。通常建议谨慎使用指针间接寻址,并在使用多层间接寻址时仔细考虑代码的设计。

希望您能理解。如有其他疑问,请随时联系我。谢谢!

运行时指针间接寻址的层数取决于你所使用的特定编程语言、编译器以及硬件架构。在大多数实际场景中,由于内存限制以及硬件或编译器的局限性等因素,间接寻址的层数存在一个实际的上限。然而,具体的限制可能有所不同。

例如,在C和C++这类语言中,C标准并未对间接寻址的层数定义具体的限制。它最终取决于可用内存以及硬件和编译器处理间接寻址的能力。

大家好,尤其是 @skillian@Metalymph

我刚想起了我混淆的概念。看这段代码:

type MyStruct struct {
    Field1 string
    Field2 int
}

var s *MyStruct = &MyStruct{"hello", 42} // 编译通过
var t **MyStruct = &&MyStruct{"hello", 42} // 编译不通过
var u **MyStruct = &(&MyStruct{"hello", 42}) // 编译不通过

这就是我想到的限制。所以你可以有“无限”的指针间接引用,但不能连续使用两次取址运算符。

顺便问一下,这是为什么?请提供更多细节。

@skillian 为什么在你的 Playground 示例中,限制是 1023 次?为什么我不能间接引用 1024 次?

在Go语言中,指针间接引用的层级在运行时没有硬性上限限制。理论上,你可以创建任意层级的指针(例如 ***int),只要内存允许。然而,实际中过深的指针层级通常不实用,且可能影响代码可读性。

Go语言规范未明确指定指针层级的最大限制,但受限于编译器和运行时系统的实现细节。例如,编译器可能对嵌套层级有内部限制,但这通常远超过实际需求。以下是一个示例,展示多层指针的声明和使用:

package main

import "fmt"

func main() {
    var a int = 42
    var p1 *int = &a
    var p2 **int = &p1
    var p3 ***int = &p2
    var p4 ****int = &p3

    // 通过多级指针访问值
    fmt.Println(****p4) // 输出: 42

    // 修改值
    ****p4 = 100
    fmt.Println(a) // 输出: 100
}

在这个例子中,我们创建了四级指针(****int),并成功进行了读写操作。你可以继续增加层级,但过度使用会导致代码难以维护。如果遇到编译错误,可能是由于编译器实现限制,但这种情况在标准Go工具链中极为罕见。

heidi:

顺便问一下,为什么是这样?请提供更多细节。

& 运算符用于获取其操作数的地址,但这仅在要获取地址的值是可寻址的时才有效。所以你可以这样做:

var i int = 5
var p *int = &i

因为这意味着将 5 存入 i,然后获取 i 的地址并将其存入 p。然而,你不能这样做:

var p *int = &5

因为你要求获取 5 的地址,但这到底意味着什么呢?指针必须指向某个东西

对此有一个例外:var s *MyStruct = &MyStruct{...}。这是 Go 中的一个特殊情况,本质上等同于:

var s *MyStruct = new(MyStruct)
*s = MyStruct{"hello", 42}

我猜测语言设计者认为指向结构体的指针使用非常普遍,因此他们可以接受添加这种“魔法”,允许你获取结构体字面量的地址,但他们没有进一步允许你获取结构体字面量地址的地址,就像他们不允许你获取其他字面量值的地址一样。

heidi:

在你的 Playground 示例中,为什么限制是 1023?为什么我不能间接引用 1024 次?

这里有 1024 次间接引用:最后一次间接引用被存储到 p 本身。据我所知,你可以不断复制粘贴 * 符号,并将计数增加到任意多。不过,我的本意是让这个例子看起来很傻。如果你需要 1024+ 次间接引用,我想我们真的很想看看你在编写什么代码!

回到顶部