英文:
Why are 'new' and 'make' not reserved keywords?
问题
启用语法高亮功能后,像这个问题的答案中使用 new 作为变量名时会分散注意力。
我试图想出只有关键字的子集会被保留而无法找到一个好的理由。
编辑:这个问题的替代标题:
为什么 Go 的预声明标识符不被保留?
英文:
With syntax highlighting enabled, it's distracting while reading code like answer to this question with new used as a variable name.
I'm trying to think of a reason why only a subset of keywords would be reserved and can't come up with a good one.
Edit: Alternate title for this question:
Why are Go's predeclared identifiers not reserved ?
答案1
得分: 4
这是因为new
和make
并不是真正的关键字,而是内置函数。
如果你查看保留关键字的完整列表,你也不会看到len
或cap
...
英文:
That's because new
and make
aren't really keywords, but built-in functions.
If you examine the full list of the reserved keywords, you won't see len
or cap
either...
答案2
得分: 2
简而言之,在你自己的声明中使用预定义标识符不会使你的代码产生歧义。
new
和make
是内置函数之一,还有许多其他内置函数。在builtin
包的文档中可以看到完整的列表。
关键字是经过精心选择的一小组保留字。你不能将关键字用作标识符,因为这可能会使解释你的源代码变得模糊不清。
内置函数是特殊函数:你可以在没有任何导入的情况下使用它们,并且它们的参数和返回列表可能会有所不同。你可以使用与内置函数同名的函数或变量进行声明,因为你的代码仍然是明确的:在作用域中,你的标识符将“胜出”。
如果你将关键字用作标识符,你将无法访问到你的实体,因为尝试通过名称引用它将始终表示关键字而不是你的标识符。
看看下面这个使用内置函数make
和内置类型int
的预定义标识符的例子(不建议在生产代码中使用)(在Go Playground上试一试):
make := func() string {
return "hijacked"
}
int := make() // 完全没问题,变量'int'将是一个字符串
fmt.Println(int) // 输出"hijacked"
如果你可以将关键字用作标识符,即使是解释声明也会让编译器头疼:下面的代码会有什么含义?
-
func()
- 是调用你命名为func
的函数,还是一个没有参数和返回类型的函数类型? -
import()
- 是一个分组导入声明(并且没有导入任何内容),还是调用我们命名为import
的函数? -
...
英文:
In short: because using predeclared identifiers in your own declarations don't make your code ambiguous.
new
and make
are builtin functions, amongst many others. See the full list in the doc of the builtin
package.
Keywords are a carefully chosen small set of reserved words. You cannot use keywords as identifiers because that could make interpreting your source ambiguous.
Builtin functions are special functions: you can use them without any imports, and they may have varying parameter and return list. You are allowed to declare functions or variables with the names of the builtin functions because your code will still remain unambiguous: your identifier in scope will "win".
If you would use a keyword as an identifier, you couldn't reach your entity because an attempt to refer to it by its name would always mean the keyword and not your identifier.
See this dirty example of using the predeclared identifiers of the builtin function make
and the builtin type int
(not recommended for production code) (try it on the Go Playground):
make := func() string {
return "hijacked"
}
int := make() // Completely OK, variable 'int' will be a string
fmt.Println(int) // Prints "hijacked"
If you could use keywords as identifiers, even interpreting declarations would cause headache to the compiler: what would the following mean?
-
func()
- is it calling your function namedfunc
or is it a function type with no params and no return types? -
import()
- is it a grouped import declaration (and importing nothing) or calling our function namedimport
? -
...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论