首页 > 其他分享 >Go语言声明语法

Go语言声明语法

时间:2022-11-13 02:33:22浏览次数:85  
标签:int 语法 类型 Go 声明 表达式

GO语言声明语法

原文地址

介绍

Go新手想知道为什么Go的声明语法与C语言等的传统声明语法不同。在这篇文章中,我们将比较这两种方法,并解释为什么Go的声明是这样的。

C语法

首先,让我们谈谈C语言的语法。C使用了一个不寻常但聪明的声明语法。没有使用特殊的语法来描述类型,而是编写一个涉及被声明字段的表达式,并说明该字段的类型。即

int x;

声明x为int类型: 表达式x将具有int类型。一般来说,要弄清楚新变量的类型,需要编写一个涉及该变量的表达式,然后将基本类型放在表达式左边,将表达式放在右边。

比如

int *p;
int a[3];

声明 p 是指向 int 的指针,因为 *p 具有 int 类型,并且 a 是 int 数组,因为a[3]是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)

这个表达式开始变得难以阅读。

当然,我们还可以在声明函数时省略参数名,可以这样声明

int main(int, char *[])

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

char *argv[]

从它的声明中去掉名字来构造它的类型。但是这个例子还不够明显

如果你不命名参数,看看 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 之间没有直接对应关系。(我们将在下一节中回到指针)您以单独的语法为代价获得声明的清晰。

现在考虑函数。让我们将main的声明转换成 Go 中的样子,尽管 Go 中的 main 函数不带参数:

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

从表面上看,除了从char数组字符串数组的变化之外,它与 C 并没有太大区别,但从左到右读起来很流畅:

函数 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的“顺时针/螺旋规则”

标签:int,语法,类型,Go,声明,表达式
From: https://www.cnblogs.com/INnoVationv2/p/16885304.html

相关文章

  • golang:break,continue,return,goto使用区别
    break条件满足,跳出整个循环continue条件满足,跳出这次循环,但继续执行后面的循环return返回数据,结束当前函数或程序运行gotogo语言的goto可以无条件的转移到程序中指......
  • MongoDB导入导出备份数据
    需要提前安装mongodb-database-tools参考:centos离线安装mongodb-database-tools导出数据常用的导出有两种:mongodump和mongoexport,两种方式的区别:1、mongodump导出的文件......
  • Django更换数据库和迁移数据方案
    前言双十一光顾着买东西都没怎么写文章,现在笔记里还有十几篇半成品文章没写完…今天来分享一下Django项目切换数据库和迁移数据的方案,网络上找到的文章方法不一,且使......
  • wsl升级到wsl2 不升级导致go dlv以及远程debug使用不了
    wsl升级到wsl22022.05.1020:44:42字数392阅读2,087https://docs.microsoft.com/zh-cn/windows/wsl/install-win10安装ubuntu20.04子系统通过微软商店、powers......
  • gost容器代理
    项目地址https://github.com/ginuerzh/gost命令行使用代理#设置代理netshwinhttpsetproxy192.168.10.20:7890netshwinhttpsetproxyproxy-server="http=192......
  • Go之time包日期操作,时间戳与日期相互转换
    在Go中,时间操作需要导入time包获取当前时间packagemainimport("fmt""time")funcmain(){//获取当前时间t:=time.Now()fmt.Print......
  • 30分钟学完Python基础语法
    30分钟学完Python基础语法,有一门面向对象语言的基础,30分钟足够看一遍Python的基础了。基础语法#缩进取代大括号#用换行取代分号,也可以使用分号,无所谓#输出print();#输......
  • vue3.2 setup语法糖,多个API解释
    前言在vue3中删除了vue2中的data函数,因此,vue3.0要在template中使用某些变量就必须在最后return出来,多次声明变量,不太方便,也不太友好。而在vue3.2版本之后,我们只需在......
  • mongodb基本操作命令及数据类型(一)
    从MongoDB3.2,它使用WiredTiger作为其默认的存储引擎,也可以通过以下语句查询默认的存储引擎1.mongodb入门命令showdatabases/dbs查看当前数据库(test(测试库)、admin......
  • Golang:error包错误处理
    (目录)1、Golangerror包内建error接口//builtin.gotypeerrorinterface{Error()string}实现error接口//errors.gopackageerrorstypeerrorStrings......