Go's Declaration Syntax(Go的声明语法)

以下翻译自Rob Pike 编写的Go's Declaration Syntax(Go的声明语法)

介绍

Go的新人想知道为什么声明语法与C系列中建立的传统不同。在这篇文章中,我们将比较两种方法,并解释为什么Go的声明看起来很像。

C语法

首先,说说C语法。C采用了一种不同寻常且聪明的方法来生命语法。不是用特殊的语法描述类型,而是编写涉及声明的项的表达式,并说明该表达式将具有的类型,例如

  int x;

将x声明为int:表达式‘x’将具有int类型。通常,要弄清楚如何编写新的变量的类型,请编写一个涉及变量的表达式,该变量的计算结果为基本类型,然后将基本类型放在左侧,将表达式放在右侧。
例如下边的声明

  int *p;
  int a[3];

声明p是一个指向int的指针,因为'*p'的类型是int,而a[3]是一个int类型的数组,因为有类型int(忽略特定的索引值,它被认为是数组的大小)。
函数是什么样子呢?最初,C的函数声明再括号之外编写参数类型,如下所示:

  int main(argc, argv)
    int argc;
    char *argv[];
  { /* ... */ }

同样,我们看到main是一个函数,因为表达式main(argc, argv)返回一个int类型的值,在现在符号中我们写做

  int main(int argc, char *argv[]) { /* ... */ }

但基本的结构是一致的。
这是一个聪明的句法概念,适用于简单类型,但很快就糊涂了。一个著名的例子是声明一个函数指针。按照规则,你将看到如下:

  int (*fp)(int a, int b);

这里,fp是一个指向函数的指针,因为如果你编写表达式(* fp)(a,b),你将调用一个返回int的函数。如果fp的一个参数本身就是一个函数怎么办?

  int (*fp)(int (*ff)(int x, int y), int b)

这就非常难于理解。
当然,我们在声明函数时可以省略参数的名称,因此可以声明main为:

  int main(int, char *[])

回想一下,argv是这样声明的

  char *argv[]

所以你从它的声明中间删除名称来构造它的类型。但是,通过将其名称放在中间来声明char * []类型的东西并不明显。
如果你没有命名参数,看看fp的声明会发生什么:

  int (*fp)(int (*)(int, int), int)

将名称放在哪里不仅不明显

  int (*)(int, int)

根本不清楚它是一个函数指针声明。如果返回类型是函数指针怎么办?

  int (*(*fp)(int (*)(int, int), int))(int, int)

甚至很难看到这个声明是关于fp的。
您可以构造更详细的示例,但这些示例将说明C的声明语法可能带来的一些困难。
不过,还有一点需要做。因为类型和声明语法是相同的,所以很难解析中间类型的表达式。这就是为什么,例如,C 强制转换总是将类型括起来,例如:

  (int)M_PI

Go语法

C系列之外的语言通常在声明中使用不同的类型语法。虽然它是一个单独的点,但通常首先出现名称,通常后面跟冒号。因此,我们上面的例子变得类似(用虚构但用说明性的语言)

  x: int
  p: pointer to int
  a: array[3] of int

这些声明很清楚,如果详细 - 你只需从左到右阅读它们。 Go从这里开始提示,但为了简洁起见,它会删除冒号并删除一些关键字:

  x int
  p *int
  a [3]int

[3] int表面上与如何在表达式中使用a之间没有直接的对应关系。(我们将在下一节回到指点。)您可以清楚地了解单独语法的成本。
现在考虑函数。让我们在Go中读取main的声明,尽管Go中的真正主要函数没有参数:

  func main(argc int, argv []string) int

表面上看起来与C没什么不同,除了从char数组到字符串的变化,但它从左到右读得很好:
function main接受一个int和一个字符串切片并返回一个int。
删除参数名称,它也很清楚 - 它们总是第一个,所以没有混淆。

  func main(int, []string) int

这种从左到右的风格的一个优点是它的工作效果随着类型变得更加复杂。
这是一个函数变量的声明(类似于C中的函数指针):

  f func(func(int,int) int, int) int

或者如果f返回一个函数

  f func(func(int,int) int, int) func(int, int) int

它仍然从左到右清晰地读取,并且显而易见的是声明了哪个名称 - 名称首先出现。
类型和表达式语法之间的区别使得在Go中编写和调用闭包很容易:

  sum := func(a, b int) int { return a+b } (3, 4)

指针

指针是证明规则的例外。
请注意,例如,在数组和切片中,Go的类型语法将括号放在类型的左侧,但表达式语法将它们放在表达式的右侧:

  var a []int
  x = a[1]

为了熟悉,Go的指针使用来自C的*表示法,但我们无法使自己对指针类型进行类似的反转。因此指针就像这样工作:

  var p *int
  x = *p

我们不能这么表达:

  var p *int
  x = p*

因为后缀*会与乘法混淆。我们可以使用Pascal ^,例如:

  var p ^int
  x = p^

也许我们应该(并为xor选择另一个运算符),因为类型和表达式上的前缀星号以多种方式使事情复杂化。例如,虽然可以写

  []int("hi")

作为转换,如果以*开头,则必须将该类型括起来:

  (*int)(nil)

如果我们愿意放弃*作为指针语法,那么这些括号将是不必要的。
因此Go的指针语法与熟悉的C形式相关联,但这些关系意味着我们不能完全摆脱使用括号来消除语法中的类型和表达式的歧义。
总的来说,我们相信Go的类型语法比C语言更容易理解,特别是当事情变得复杂时。

最后

Go的声明从左到右阅读。有人指出C是螺旋式阅读!参见David Anderson的“The "Clockwise/Spiral Rule(顺时针/螺旋规则)"

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335