Go 语言设计者 Robert Griesemer 和 Ian Lance Taylor 近日在 Golang 官方论坛发帖讨论关于泛型及其括号使用的问题。

他们提到很多人表达了对泛型语法的担忧,特别是在类型参数声明和函数实例以及泛型的括号选择方面。
常见的计算机键盘提供了四对单字符对称括号,分别是小括号 ( )、方括号 [ ]、花括号 { } 以及尖括号 < >。基于此,他们解释了目前泛型草案在示例代码中使用小括号的原因。首先,Go 使用花括号来划分代码块、复合字面量(composite literals)和一些复合类型,因此几乎不可能在没有严重语法问题的情况下将花括号用于泛型。至于尖括号,解析器在某些情况下要求 <> 需要 unbounded lookahead。
所以只剩下 ( ) 和 [ ] 可供选择。然而缺少修饰的方括号会在数组和 slice 的类型声明中造成歧义,在解析索引表达式时也会引起小程度的歧义。因此在设计之初他们决定使用小括号,因为小括号似乎更符合 Go 语言的风格,而且看起来问题最少。
为了使小括号正常工作,并且为了向后兼容,他们表示不得不在类型参数列表中引入type关键字。最后,他们在参数列表、复合字面量和嵌入类型中发现了额外的解析歧义,而这些歧义需要嵌套更多的小括号来解决。不过即便如此,他们还是决定继续使用小括号,因为当时还有更重要的设计问题需要解决。
现在他们决定重新考虑这个最初的决定。如果仅使用方括号声明类型参数,那么声明数组的方式如下所示:
type A [N]E
不过这就无法与泛型的声明进行区分:
type A[N] E
但如果能接受额外的type关键字,那么歧义就会消失:
type A[type N] E
此外,使用小括号时产生的歧义似乎不会出现在方括号中。下面是一些使用方括号但不需要额外嵌套小括号的例子:
using () using []
func f((T(int)) func f(T[int])
struct{ (T(int)) } struct{ T[int] }
interface{ (T(int)) } interface{ T[int] }
[](T(int)){} []T[int]{}
为了更好地理解以及进行测试,他们表示将开始对原型实现进行修改,让泛型能使用小括号或方括号(注意不能同时混用,只能使用其中一种)。这些修改将首先提交到 dev.go2go 分支,最终会出现在 Go playground 上。
Robert 和 Ian 表示,除了使用方括号,还有另外经过充分研究的符号可以选择,这些方案能让他们做出更明智的决定。
更多讨论查看 https://groups.google.com/forum/#!topic/golang-nuts/7t-Q2vt60J8
For ambiguities with angle brackets consider the assignment
a, b = w < x, y > (z)
Without type information, it is impossible to decide whether the right-hand side of the assignment is a pair of expressions
(w < x), (y > (z))
or whether it is a generic function invocation that returns two result values
(w<x, y>)(z)
In Go, type information is not available at compile time. For instance, in this case, any of the identifiers may be declared in another file that has not even been parsed yet.
也可以考虑用竖线或其它符号来分隔泛型参数.
然而objc当年是和c++齐头并进的, 都有互相鄙视的资本.
go比c++/java晚了几十年, 为了不同而不同?
:neckbeard: 看来十多岁都是玩杀马特的年纪.
c++/java/c# 等全部采用<>括号,golang这是为了不同而不同吧。
a, b := x < y, j > i