搜索
首页后端开发GolangGo语言的词法元素有几类
Go语言的词法元素有几类Jan 12, 2023 am 10:03 AM
golanggo语言

Go语言的词法元素有5类:1、标识符,由若干字母(由Unicode编码即可)、下划线和数字组成的字符序列;2、关键字,是被编程语言保留而不让编程人员作为标识符使用的字符序列,也可以称为保留字;3、操作符,是用于执行特定算术运算或逻辑操作的符号;4、分隔符;5、字面量,是值的一种标记法。

Go语言的词法元素有几类

本教程操作环境:windows7系统、GO 1.18版本、Dell G3电脑。

Go语言的语言符号又称为词法元素,共包括5类:标识符(identifier)、关键字(keyword)、操作符(operator)、分隔符(delimiter)、以及字面量(literal),它们是组成Go语言代码和程序的最基本单位。

一般情况下,空格符、水平制表符、回车符和换行符都会被忽略,除非它们作为多个语言符号之间的分隔符的一部分。在Go语言中不需要显示地插入分号,在必要时,Go语言会自动为代码插入分号以进行语句分隔。

Go语言代码由若干个Unicode字符组成,Go语言的所有源代码都必须由Unicode编码规范的UTF-8编码格式进行编码(也就是说编写的Go语言源码文件必须是UTF-8编码格式的)。

Go语言的语言符号又称为词法元素,共包括5类:标识符(identifier)、关键字(keyword)、操作符(operator)、分隔符(delimiter)、以及字面量(literal)。一般情况下,空格符、水平制表符、回车符和换行符都会被忽略,除非它们作为多个语言符号之间的分隔符的一部分。在Go语言中不需要显示地插入分号,在必要时,Go语言会自动为代码插入分号以进行语句分隔。

Go语言代码由若干个Unicode字符组成,Go语言的所有源代码都必须由Unicode编码规范的UTF-8编码格式进行编码(也就是说编写的Go语言源码文件必须是UTF-8编码格式的)。

1、标识符

Go语言的标识符是由若干字母(由Unicode编码即可)、下划线和数字组成的字符序列;该字符序列的第一个字符必须为字母。

注意:

  • 在Go语言代码中,每一个标识符都必须在使用前进行声明。

  • 一个声明将一个非空的标识符与一个常量、类型、变量、函数或代码包绑定在一起。

  • 在同一个代码块中,不允许重复声明同一个标识符(除了赋值语句例外)。

  • 在一个源码文件和一个代码包中的标识符都需要遵循此规则。

  • 一个已被声明的标识符的作用域与其直接所属的代码块的范围相同。

严格来讲,代码包声明语句并不算是一个声明。因为代码包名称并不会出现在任何一个作用域中。代码包声明语句的目的是为了鉴别若干源码文件是否属于同一个代码包,或者指定导入代码包时的默认代码包引用名称。

限定标识符用来访问其他代码包中的变量或类型。例如,当我需要访问代码包os中名为O_RDONLY的常量时,需要这样写os.O_RDONLY。

限定标识符能够使用,需要满足两个前提条件:

  • 要访问的代码包必须被事先导入;

  • 这个代码包中的标识符必须是可导出的。

一个可导出的标识符也需要满足两个前提条件:

  • 标识符名称中的第一个字符必须为大写(Go语言根据标识符名称中的第一个字符的大小写来确定这个标识符的访问权限的,当标识符名称的第一个字符为大写时,其访问权限为“公开的”,也就是该标识符可以被任何代码包中的任何代码通过限定标识符访问到;当标识符的第一个字符为小写时,其访问权限就是"包级私有的",也就是只有与该标识符同在一个代码包的代码才能够访问到它);

  • 标识符必须是被声明在一个代码包中的变量或者类型的名称,或者是属于某个结构体类型的字段名称或方法的名称。

Go语言的预定义标识符:

  • 所有基本数据类型的名称。
  • 接口类型error
  • 常量true,false和iota
  • 所有内建函数的名称,即append、cap、close、complex、copy、delete、imag、len、make、new、panic、print、println、real和recover。

Go语言中有一个空标识符,它由一个下划线表示,一般用于一个不需要引入一个新绑定的声明中。例如,当我们只想执行一下某个代码包中的初始化函数,而不需要使用这个代码包中的任何程序实体的时候,可以编写如下导入语句:

import _ "runtime/cgo"1.

其中,"runtime/cgo"代表了一个标准库代码包的标识符。

2、关键字

关键字(也称为保留字)是被编程语言保留而不让编程人员作为标识符使用的字符序列。

类别 关键字
程序声明 import, package
程序实体声明和定义 chan, const, func, interface, map, struct, type, var
程序控制流程 go, select, break, case, continue, default, defer, else, fallthrough, for, goto, if, range, return, switch

在Go语言中,程序实体的声明和定义是建立在其数据类型的体系之上的。例如关键字chan、func、interface、map和struct,分别于Go语言的复合数据类型Channel(通道)、Function(函数)、Interface(接口)、Map(字典)和Struct(结构体)相对应。

程序控制流程的关键字,一共15个。其中go和select,这两个主要用于Go语言并发编程。

3、字面量

简单来说,字面量就是值的一种标记法。但是,在Go中,字面量的含义要更加广泛一些。

Go语言代码中用到的字面量有以下3类:

1、表示基础数据类型值的各种字面量。例如,表示浮点数类型值的12E-3。

2、构造各种自定义的复合数据类型的类型字面量。例如,下面表示一个名称为Person的自定义结构体类型:

type Person struct {
	Name 	string
	Age	uint8
	Address	string
}

3、表示复合数据类型的值的复合字面量

被用来构造类型Struct(结构体)、Array(数组)、Slice(切片)和Map(字典)的值。例如,下面的字面量用于表示上面名称为Person的结构体类型的值:

Person {
	Name:"Huazie",
	Age: "21",
	Address: "Nanjing, China"
}

注意:
对复合字面量的每次求值都会导致一个新的值被创建。因此,如上该复合字面量每被求值一次就会创建一个新的Person类型的值。

Go语言不允许在一个此类的复合字面变量中,出现重复的键。如下都是错误,无法通过编译,因为键都有重复。

//表示结构体类型值,有重复的键 Name
Person {Name: "Huazie",Age: "21", Name: "Unknown"}
//表示字典类型值,有重复的键 Age
map[string]string{ Name: "Huazie",Age: "21", Age: "21"}
//表示切片类型值,有重复的键 0
[]string{0: "0", 1: "1", 0: "-1"}

4、类型

一个类型确定了一类值的集合,以及可以在这些值上施加的操作。类型可以由类型名称或者类型字面量指定,分为基本类型和复合类型,基本类型的名称可以代表其自身。

var bookName string1.

如上声明了一个类型为string(基本类型中的一个)、名称为bookName的变量。

其他基本类型(预定义类型)有bool、byte、rune、int/uint、int8/uint8、int16/uint16、int32/uint32、int64/uint64、float32、float64、complex64和complex128。除了bool和string之外的其他基本类型也叫做数值类型。

复合类型一般由若干(也包括零)个其他已被定义的类型组合而成。复合类型有Channel(通道)、Function(函数)、Interface(接口)、Map(字典)、Struct(结构体)、Slice(切片)、Array(数组)和Pointer(指针)。

Go语言中的类型又可以分为静态类型和动态类型。一个变量的静态类型是指在变量声明中给出的那个类型。绝大多数类型的变量都只有静态类型。唯独接口类型的变量例外,它除了拥有静态类型之外,还拥有动态类型(接口类型在后面会讲到)。

每一个类型都会有一个潜在类型。如果这个类型是一个预定义类型(也就是基本类型),或者是一个由类型字面量构造的复合类型,那么它的潜在类型就是它自身。如string类型的潜在类型就是string类型,上面自定义的Person类型的潜在类型就是Person。如果一个类型并不属于上述情况,那么这个类型的潜在类型就是类型声明中的那个类型的潜在类型。

如下声明一个自定义类型

type MyString string1.

如上可以把类型MyString看作string类型的一个别名类型,那么MyString类型的潜在类型就是string类型。Go语言基本数据类型中的rune类型可以看作是uint32类型的一个别名类型,其潜在类型就是uint32。

注意:

  • 类型MyString和类型string是两个不相同的类型。不能将其中一个类型的值赋给另一个类型的变量。
  • 别名类型与它的源类型的不同仅仅体现在名称上,它们的内部结构是一致的;下面的类型转换的表达式都是合法的:MyString(“ABC”) 和string(MyString(“ABC”))。这种类型转换并不会创建新的值。

一个类型的潜在类型具有可传递性,如下:

type iString MyString1.

则类型isString的潜在类型就是string类型。

这里声明一个类型,如下:

type MyStrings [3]string1.

**注意:**类型MyStrings的潜在类型并不是[3]string。[3]string既不是一个预定义的类型,也不是一个由类型字面量构造的复合类型,而是一个元素类型为string的数组类型。

根据上面的定义可知类型MyStrings的潜在类型就是[3]string的潜在类型string。

Go语言规定,一个数组类型的潜在类型决定了在该类型的变量中可以存放哪一个类型的元素。

5、操作符

操作符就是用于执行特定算术运算或逻辑操作的符号。(这里不详细讲解了,跟C语言的操作符类似),不过Go语言中没有三元操作符,所以除了一元操作符以外都必定是二元操作符。Go语言一共有21个操作符,包括算术操作符、比较操作符、逻辑操作符、地址操作符和接收操作符。

符号 说明 示例



&& 逻辑与操作。二元,逻辑操作符 true && false //表达式结果是false
== 相等判断操作。二元,比较操作符 “abc” == “abc”//结果是true
!= 不等判断操作。二元,比较操作符 “abc” != “Abc”//结果是true
89d76cdeb80d41655512e16218266dfb 大于判断操作。二元,比较操作符 3 > 2 //表达式结果是true
>= 大于或等于。二元,比较操作符 3 >= 2 //表达式结果是true
+ 表示求和,一元又是二元,算术操作符 +1 //结果为1 (1+2) //结果是3
- 表示求差,一元又是二元,算术操作符 -1 //结果为-1 (1 – 2) //结果是-1
\ 按位或操作,二元,算术操作符 5 \ 11 //表达式的结果是15
^ 按位异或,一元又是二元,算术操作符 511//结果是14(5)//结果是-6
* 求积或取值,一元,二元,算术,地址 *p //取值操作
/ 求商操作,二元,算术操作符 10 / 5 //表达式的结果为2
% 求余数操作,二元,算术操作符 12 % 5 //表达式的结果为2
84403b5ba4b046b5dad37535a28457ce> 按位右移操作,二元,算术操作符 4 >> 2 //表达式的结果为1
& 按位与操作,一元,二元,算术,地址 &v //取地址操作
&^ 按位清除操作,二元,算术操作符 5 &^ 11 //表达式的结果为4
! 逻辑非操作,一元,逻辑操作符 !b //若b为true,结果为false
c096ee1858d9905aff850336040c07fc>    &    &^
4 +     -     \     ^
3 ==     !=     8056e466eb4ac2e45f0ee1fdc891a78a     >=
2 &&
1

扩展知识:表达式

基本表达式

(1) 使用操作数来表示;

(2) 使用类型转换来表示;

(3) 使用内建函数调用来表示;

(4) 一个基本表达式和一个选择符号组成选择表达式;

例如,如果在一个结构体类型中存在字段f,我们就可以在这个结构体类型的变量x上应用一个选择符号来访问这个字段f,即x.f。其中,.f就是一个选择符号。注意:前提是这个变量x的值不能是nil。在Go语言中,nil用来表示空值。

(5) 一个基本表达式和一个索引符号组成索引表达式;

索引符号由狭义的表达式(仅由操作符和操作数组成)和外层的方括号组成,例如[]int{1,2,3,4,5}[2]就是索引表达式。
Go语言允许如下的赋值语句:

v, ok := a[x]1.

如上a为字典类型,x为字典的键。该索引表达式的结果是一对值,而不是单一值。第一个值的类型就是该字典类型的元素类型,而第二个值则是布尔类型。与变量ok绑定的布尔值代表了在字典类型a中是否包含了以x为键的键值对。如果在a中包含这样的键值对,那么赋给变量ok的值就是true,否则就为false。

**注意:**虽然当字典类型的变量a的值为nil时,求值表达式a[x]并不会发生任何错误,但是在这种情况下对a[x]进行赋值却会引起一个运行时恐慌( Go语言异常)。

(6) 一个基本表达式和一个切片符号组成切片表达式;

切片符号由2个或3个狭义的表达式和外层的方括号组成,这些表达式之间由冒号分隔。切片符号作用与索引符号类似,只不过索引符号针对的是一个点,切片符号针对的是一个范围。例如,要取出一个切片[]int{1,2,3,4,5}的第二个到第四个元素,那么可以使用切片符号的表达式[]int{1,2,3,4,5}[1:4],该结果还是一个切片。

切片表达式a[x:y:z],a是切片符号[x:y]的操作对象。其中,x代表了切片元素下界索引,y代表了切片的元素上界索引,而z则代表了切片的容量上界索引。约束如下:

0 <= 元素下界索引 <= 元素上界索引 <= 容量上界索引 <= 操作对象的容量

设a的值为[]int{1,2,3,4,5},则切片表达式a[:3]等同于a[0:3],这是因为切片符号的元素下界索引的默认值为0,相应的元素上界的索引的默认值为操作对象的长度值或容量值,即切片表达式a[3:]等同于a[3:5]。同样,切片表达式a[:]等同于复制a所代表的值并将这个复制品作为表达式的求值结果。

注意: UTF-8 编码格式会以3个字节来表示一个中文字符,而切片操作是针对字节进行的。

如果有“Go并发编程实战”的字符串类型的变量a,那么切片表达式a[1:3]的结果不是“o并”,而a[1:5]的结果才是“o并”。

(7) 一个基本表达式和一个类型断言符号组成;

类型断言符号以一个英文句号为前缀,并后跟一个被圆括号括起来的类型名称或类型字面量。类型断言符号用于判断一个变量或常量是否为一个预期的类型,并根据判断结果采取不同的响应。例如,如果要判断一个int8类型的变量num是否是int类型,可以这样编写表达式:interface{}(num).(int)。

对于一个求值结果为接口类型值的表达式x和一个类型T,对应的类型断言为:

x.(T)1.

该表达式的作用是判断“x不为nil且存储在其中的值是T类型的”是否成立。

如果T不是一个接口类型,那么x.(T)会判断类型T是否为x的动态类型(一个变量的动态类型就是在运行期间存储在其中的值的实际类型);而这个实际类型必须是该变量声明的那个类型的一个实现类型,否则就根本不可能在该变量中存储这一类型的值。所以类型T必须为x的类型的一个实现类型,而在Go语言中只有接口类型可以被其他类型实现,所以x的求值结果必须是一个接口类型的值。

所以上面表达式interface{}(num).(int)中表达式interface{}(num)的含义就是将变量num转换为interface{}类型的值(即它的结果值是接口类型的),而这刚好符合前面的定义。

知识点: interface{}是一个特殊的接口类型,代表空接口。所有类型都是它的实现类型。

在对变量的赋值或初始化的时候,也可以使用类型断言,如下:

v, ok := x.(T)1.

当使用类型断言表达式同时对两个变量进行赋值时,如果类型断言成功,那么赋给第一个变量的将会是已经被转换为T类型的表达式x的求值结果,否则赋给第一个变量的就是类型T的零值。布尔类型会被赋给变量ok,它体现了类型断言的成功(true)与否(false)。

注意: 在这种场景下,即使类型断言失败也不会引发运行时恐慌。

(8) 一个基本表达式和一个调用符号组成。

调用符号只针对于函数或者方法。与调用符号组合的基本表达式不是一个代表代码包名称(或者其别名)的标识符就是一个代表结构体类型的方法的名称的标识符。调用符号由一个英文句号为前缀和一个被圆括号括起来的参数列表组成,多个参数列表之间用逗号分隔。例如,基本表达式os.Open(“/etc/profile”)表示对代码包os中的函数Open的调用。

可变长参数

如果函数f可以接受的参数的数量是不固定的,那么函数f就是一个能够接受可变长参数的函数,简称可变参函数。在Go语言中,在可变参函数的参数列表的最后总会出现一个可变长参数,这个可变长参数的类型声明形如…T。Go语言会在每次调用函数f的时候创建一个切片类型值,并用它来存放这些实际函数。这个切片类型值的长度就是当前调用表达式中与可变长参数绑定的实际参数的数量。

可变参函数appendIfAbsent声明如下(函数体省略):

func appendIfAbsent(s []string, t ...string) []string1.

针对此函数的调用表达式如下:

appendIfAbsent([]string(“A”,”B”,”C”),”C”,”B”,”A”)1.

其中,与可变参数t绑定的切片类型值为[]string{”C”,”B”,”A”},包含了实际参数”C”,”B”和”A”。

也可以直接把一个元素类型为T的切片类型值赋给…T类型的可变长参数,如下调用:

appendIfAbsent([]string(“A”,”B”,”C”), []string(”C”,”B”,”A”)...)1.

或者如果有一个元素类型为stirng的切片类型的变量s的话,如下调用:

appendIfAbsent([]string(“A”,”B”,”C”), s...)1.

对于将切片类型的变量赋给可变长参数的情况,Go语言不会专门创建一个切片类型值来存储其中的实际参数。因为,这样的切片类型值已经存在了,可变长参数t的值就是变量s的值。

【相关推荐:Go视频教程编程教学

以上是Go语言的词法元素有几类的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
go语言有没有缩进go语言有没有缩进Dec 01, 2022 pm 06:54 PM

go语言有缩进。在go语言中,缩进直接使用gofmt工具格式化即可(gofmt使用tab进行缩进);gofmt工具会以标准样式的缩进和垂直对齐方式对源代码进行格式化,甚至必要情况下注释也会重新格式化。

聊聊Golang中的几种常用基本数据类型聊聊Golang中的几种常用基本数据类型Jun 30, 2022 am 11:34 AM

本篇文章带大家了解一下golang 的几种常用的基本数据类型,如整型,浮点型,字符,字符串,布尔型等,并介绍了一些常用的类型转换操作。

go语言为什么叫gogo语言为什么叫goNov 28, 2022 pm 06:19 PM

go语言叫go的原因:想表达这门语言的运行速度、开发速度、学习速度(develop)都像gopher一样快。gopher是一种生活在加拿大的小动物,go的吉祥物就是这个小动物,它的中文名叫做囊地鼠,它们最大的特点就是挖洞速度特别快,当然可能不止是挖洞啦。

一文详解Go中的并发【20 张动图演示】一文详解Go中的并发【20 张动图演示】Sep 08, 2022 am 10:48 AM

Go语言中各种并发模式看起来是怎样的?下面本篇文章就通过20 张动图为你演示 Go 并发,希望对大家有所帮助!

tidb是go语言么tidb是go语言么Dec 02, 2022 pm 06:24 PM

是,TiDB采用go语言编写。TiDB是一个分布式NewSQL数据库;它支持水平弹性扩展、ACID事务、标准SQL、MySQL语法和MySQL协议,具有数据强一致的高可用特性。TiDB架构中的PD储存了集群的元信息,如key在哪个TiKV节点;PD还负责集群的负载均衡以及数据分片等。PD通过内嵌etcd来支持数据分布和容错;PD采用go语言编写。

聊聊Golang自带的HttpClient超时机制聊聊Golang自带的HttpClient超时机制Nov 18, 2022 pm 08:25 PM

​在写 Go 的过程中经常对比这两种语言的特性,踩了不少坑,也发现了不少有意思的地方,下面本篇就来聊聊 Go 自带的 HttpClient 的超时机制,希望对大家有所帮助。

go语言是否需要编译go语言是否需要编译Dec 01, 2022 pm 07:06 PM

go语言需要编译。Go语言是编译型的静态语言,是一门需要编译才能运行的编程语言,也就说Go语言程序在运行之前需要通过编译器生成二进制机器码(二进制的可执行文件),随后二进制文件才能在目标机器上运行。

golang map怎么删除元素golang map怎么删除元素Dec 08, 2022 pm 06:26 PM

删除map元素的两种方法:1、使用delete()函数从map中删除指定键值对,语法“delete(map, 键名)”;2、重新创建一个新的map对象,可以清空map中的所有元素,语法“var mapname map[keytype]valuetype”。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前By尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中