go中的结构中的无效递归类型

kfe*_*ney 38 go

我是Go编程语言的新手,我有一个创建和解释器的任务,但我遇到了以下问题:

我想将环境定义为:

type Environment struct{
    parent Environment
    symbol string
    value RCFAEValue
}

func (env Environment) lookup(lookupSymbol string) RCFAEValue{
    if lookupSymbol == env.symbol{
        return env.value
    } //if parent != nill {
        return env.parent.lookup(lookupSymbol)
}
Run Code Online (Sandbox Code Playgroud)

但我收到错误"无效的递归类型环境".根据我的研究,我将父改为*Environment.但是现在当我需要使用var类型的环境创建一个新的环境时,它会得到错误"不能使用fun_Val.ds(类型环境)作为类型*环境中的字段值".我创建环境如下:

Environment{fun_Val.ds,fun_Val.param,exp.arg_exp.interp(env)}
Run Code Online (Sandbox Code Playgroud)

我试图将此帖中的代码数量保持在一个限制,但如果您需要更多,或有其他问题,请告诉我.

Eva*_*haw 61

你需要定义Environment为:

type Environment struct {
    parent *Environment // note that this is now a pointer
    symbol string
    value  RCFAEValue
}
Run Code Online (Sandbox Code Playgroud)

否则,编译器无法确定Environment结构的大小.指针的大小是已知的,但包含自身的东西有多大?(内部结构也包含自身,内部结构也是如此,等等.)

创建环境将如下所示:

Environment{&fun_Val.ds, fun_Val.param, exp.arg_exp.interp(env)}
Run Code Online (Sandbox Code Playgroud)

  • "否则编译器无法弄清楚环境结构的大小." 那是错误的.编译器确切知道Environment结构的大小:它是无限的.编译器的这些知识是编译器拒绝代码并说"无效递归类型环境"的原因. (7认同)
  • @Atom,不是这样的:环境结构的大小是_potentially_ infinite; 当存在具有空父级的环境时,链将结束.出于这个原因,一些编译器,例如FPC,能够处理类似的定义. (4认同)
  • 为什么@JasonFruit 的评论比@Atom 的评论有更多的赞成票?这是不对的。Golang 值类型不能为 null,C++ 或 C 也不能为 null。这没有意义,因为值类型字段的内容直接存储在其使用的上下文中。所以是的,Golang 编译器知道它是无限的。当然,除非定义只是 `type A struct {A}` - 那么它是 0,但仍然无法编译,因为深度仍然是无限的。 (4认同)
  • @JasonFruit只要你使用指针就可以为空.如果没有,那么在OP示例中它肯定是*无限的,因为内部结构的空间必须被分配为外部结构空间的一部分. (2认同)