在一个作用域中重新声明的类型是否会受到外部作用域的影响?

huangapple go评论121阅读模式
英文:

Should type redeclare order in a scope be effected by outer scope?

问题

我得到了一个奇怪的错误信息cannot use []feed literal (type []feed) as type []feed in field value,经过一些调试和简化源代码,我发现这种情况似乎会产生错误:

type user struct {
    Feeds []feed
}
type feed struct{}

func fn() {
    type user struct {
        Feeds []feed // 似乎引用了外部的 feed 类型
    }
    type feed struct{}

    _ = user{
        // "cannot use []feed literal (type []feed) as type []feed in field value"
        Feeds: []feed{},
    }
}

这是预期的行为还是一个 bug?我花了一些时间阅读语言规范,但没有找到明确说明作用域中类型声明顺序应该如何工作的内容。在外部作用域中顺序无关紧要,但在内部作用域中却很不直观。

英文:

I got a strange error message cannot use []feed literal (type []feed) as type []feed in field value and after some fiddling and minimizing the source I figured out that this situation seems to produce the error:

type user struct {
	Feeds []feed
}
type feed struct{}

func fn() {
	type user struct {
		Feeds []feed // seems to refer to the outer feed type
	}
	type feed struct{}

	_ = user{
		// "cannot use []feed literal (type []feed) as type []feed in field value"
		Feeds: []feed{},
	}
}

http://play.golang.org/p/gNIGhPwAgl

Is this the intended behaviour or a bug? I've spend some time reading the language specification but can't find anything explicitly stating how type declaration order in scopes should work. It's a bit unintuitive that order does not matter in the outer scope but does in the inner.

答案1

得分: 1

这是语言规范中的规定。

引用相关部分:声明和作用域:

在函数内部声明的类型标识符的作用域从标识符在TypeSpec中开始,到最内层包含块的结束。

在函数内部声明的类型只在类型标识符(正在声明的标识符)之后的作用域内有效。在此之前是无效的。

type user struct {
    Feeds []feed // 这只能是外部的feed类型
}

type feed struct{} // 新的feed类型从这一行开始有效
英文:

This is so by the language spec.

Quoting the relevant part: Declarations and scope:

> The scope of a type identifier declared inside a function begins at the identifier in the TypeSpec and ends at the end of the innermost containing block.

Types declared inside a function are only in scope from the type identifier (being declared). Before that they are not.

type user struct {
    Feeds []feed // This can only be the outer feed type
}

type feed struct{} // new feed type is in scope from this line

答案2

得分: 0

在golang-nuts列表中找到了一篇关于这个问题的帖子(链接:https://groups.google.com/d/msg/golang-nuts/w40shSAlObk/XQvoxqbJ9v4J):

简而言之,这是因为在函数内部声明的顺序是有关系的,但在函数外部则不是。在包范围内,符号的声明顺序是根据它们的依赖关系来确定的,与它们在页面上的出现顺序无关;而在函数内部,它们是按照词法顺序声明的。稍加思考就能明白为什么这种不一致性是有道理的,尽管它确实是不一致的。
-rob

英文:

Found thread on golang-nuts list talking about this:
> Briefly, this is because order of declaration matters inside a function but does not outside. At package scope, the symbols are declared in the order that satisfies their dependencies independent of their appearance on the page; inside a function, they are declared in lexical order. A moment's reflection will show why this inconsistency has merit, although it is, well, inconsistent.
-rob

huangapple
  • 本文由 发表于 2015年9月18日 06:15:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/32640820.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定