Maison > développement back-end > Golang > le corps du texte

Il existe plusieurs types d'éléments lexicaux en langage Go

青灯夜游
Libérer: 2023-01-12 10:03:16
original
1773 Les gens l'ont consulté

Il existe 5 catégories d'éléments lexicaux dans le langage Go : 1. Les identifiants, qui sont des séquences de caractères composées de plusieurs lettres (codées par Unicode), de traits de soulignement et de chiffres 2. Les mots clés, qui sont réservés par le langage de programmation et non autorisés ; pour les programmeurs, les séquences de caractères utilisées comme identifiants peuvent également être appelées mots réservés ; 3. Les opérateurs sont des symboles utilisés pour effectuer des opérations arithmétiques ou logiques spécifiques ; 4. Les séparateurs sont une notation pour les valeurs ;

Il existe plusieurs types d'éléments lexicaux en langage Go

L'environnement d'exploitation de ce tutoriel : système Windows 7, GO version 1.18, ordinateur Dell G3.

Les symboles du langage Go sont également appelés éléments lexicaux, qui comprennent 5 catégories : identifiant, mot-clé, opérateur, délimiteur et littéral, ce sont les unités les plus élémentaires qui composent les codes et les programmes du langage Go.

Normalement, les espaces, les tabulations horizontales, les retours chariot et les sauts de ligne sont ignorés à moins qu'ils ne fassent partie du délimiteur entre plusieurs symboles de langue. Il n'est pas nécessaire d'insérer explicitement des points-virgules dans le langage Go. Si nécessaire, le langage Go insérera automatiquement des points-virgules dans le code pour séparer les instructions.

Le code du langage Go est composé de plusieurs caractères Unicode. Tous les codes sources du langage Go doivent être codés au format d'encodage UTF-8 de la spécification d'encodage Unicode (c'est-à-dire que les fichiers de code source du langage Go écrits doivent être en le format d'encodage UTF-8).

Les symboles linguistiques du langage Go sont également appelés éléments lexicaux, qui comprennent 5 catégories : identifiant(identifiant), mot-clé(mot-clé), opérateur(opérateur), séparateur(délimiteur) et littéral. (littéralement). En général, les espaces, les tabulations horizontales, les retours chariot et les sauts de ligne sont ignorés à moins qu'ils ne soient utilisés comme séparateur entre plusieurs symboles de langue. Il n'est pas nécessaire d'insérer explicitement des points-virgules dans le langage Go. Lorsque cela est nécessaire, le langage Go insérera automatiquement des points-virgules dans le code pour séparer les instructions.

Le code du langage Go est composé de plusieurs caractères Unicode. Tous les codes sources du langage Go doivent être codés au format d'encodage UTF-8 de la spécification d'encodage Unicode (c'est-à-dire que les fichiers de code source du langage Go écrits doivent être en le format d'encodage UTF-8).

1. Identifiant

L'identifiant du langage Go est une séquence de caractères composée de plusieurs lettres (codées par Unicode), de traits de soulignement et de chiffres ;

Remarque :

  • Dans le code de langue Go, chaque identifiant doit être déclaré avant utilisation.

  • Une déclaration lie un identifiant non vide à une constante, un type, une variable, une fonction ou un package de code.

  • Dans le même bloc de code, la déclaration répétée du même identifiant n'est pas autorisée (sauf pour les instructions d'affectation).

  • Les identifiants dans un fichier de code source et un package de code doivent suivre cette règle.

  • La portée d'un identifiant déclaré est la même que la portée du bloc de code auquel il appartient directement.

À proprement parler, l'instruction de déclaration du package de code n'est pas une déclaration. Parce que le nom du package de code n’apparaît dans aucune portée. L'objectif de l'instruction de déclaration du package de code est d'identifier si plusieurs fichiers de code source appartiennent au même package de code ou de spécifier le nom de référence du package de code par défaut lors de l'importation d'un package de code.

Les identifiants qualifiés sont utilisés pour accéder aux variables ou aux types dans d'autres packages de code. Par exemple, lorsque j'ai besoin d'accéder à une constante nommée O_RDONLY dans le package de code os, je dois écrire os.O_RDONLY comme ceci.

Des identifiants qualifiés peuvent être utilisés, et deux prérequis doivent être remplis :

  • Le package de codes auquel il faut accéder doit être importé au préalable

  • L'identifiant de ce package de codes doit être exportable ;

Un identifiant exportable doit également répondre à deux prérequis :

  • Le premier caractère du nom de l'identifiant doit être en majuscule (Go langue en fonction de la casse du premier caractère du nom de l'identifiant Pour déterminer les autorisations d'accès de cet identifiant, lorsque le premier caractère du nom de l'identifiant est en majuscule, ses autorisations d'accès sont « publiques », c'est-à-dire que l'identifiant peut être utilisé par n'importe quel code dans n'importe quel package de code en qualifiant l'identifiant Accès lorsque le premier caractère de l'identifiant est ; minuscule, son autorisation d'accès est "privée au niveau du package", c'est-à-dire que seul le code du même package de code que l'identifiant peut y accéder);

  • L'identifiant doit être le nom d'une variable ou d'un type déclaré dans un code package, ou le nom d’un champ ou d’une méthode appartenant à un type de structure.

Identifiants prédéfinis pour la langue Go :

  • Noms de tous les types de données de base.
  • Erreur de type d'interface
  • Constante vrai, faux et iota
  • Les noms de toutes les fonctions intégrées, à savoir append, majuscule, close, complex, copy, delete, imag, len, make, new, panic, print, println , réel et récupérer.

Il existe un identifiant vide dans le langage Go, qui est représenté par un trait de soulignement et est généralement utilisé dans une déclaration qui ne nécessite pas l'introduction d'une nouvelle liaison. Par exemple, lorsque nous souhaitons uniquement exécuter la fonction d'initialisation dans un certain package de code sans utiliser d'entités de programme dans ce package de code, nous pouvons écrire l'instruction d'importation suivante :

import _ "runtime/cgo"1.
Copier après la connexion

where, " runtime/cgo " représente l'identifiant d'un package de code de bibliothèque standard.

2. Mots-clés

Les mots-clés (également appelés mots réservés) sont des séquences de caractères réservées par les langages de programmation et ne sont pas utilisées par les programmeurs comme identifiants.

CatégorieMots clés
Déclaration de programmeimport, package
Déclaration et définition d'entité de programmechan, const, func, interface, map, struct, type,
Flux de contrôle du programmego, 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
}
Copier après la connexion

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

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

Person {
	Name:"Huazie",
	Age: "21",
	Address: "Nanjing, China"
}
Copier après la connexion

注意:
对复合字面量的每次求值都会导致一个新的值被创建。因此,如上该复合字面量每被求值一次就会创建一个新的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"}
Copier après la connexion

4、类型

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

var bookName string1.
Copier après la connexion

如上声明了一个类型为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.
Copier après la connexion

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

注意:

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

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

type iString MyString1.
Copier après la connexion

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

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

type MyStrings [3]string1.
Copier après la connexion

**Remarque :**Le type sous-jacent du type MyStrings n'est pas [3]string. [3] string n'est ni un type prédéfini ni un type composite construit à partir de littéraux de type, mais un type tableau dont le type d'élément est une chaîne.

Selon la définition ci-dessus, le type potentiel de type MyStrings est la chaîne de type potentielle de [3] chaîne.

Le langage Go stipule que le type potentiel d'un type tableau détermine quel type d'éléments peut être stocké dans une variable de ce type.

5. Opérateurs

Les opérateurs sont des symboles utilisés pour effectuer des opérations arithmétiques ou logiques spécifiques. (Je ne l'expliquerai pas en détail ici, c'est similaire aux opérateurs en langage C), mais il n'y a pas d'opérateur ternaire en langage Go, donc à l'exception des opérateurs unaires, tous les opérateurs doivent être des opérateurs binaires. Le langage Go compte un total de 21 opérateurs, dont des opérateurs arithmétiques, des opérateurs de comparaison, des opérateurs logiques, des opérateurs d'adresse et des opérateurs de réception.

2 Binaire, arithmétique, adresse Opération d'effacement au niveau du bit, binaire, opérateur arithmétique Opération NON logique, unaire, opérateur logiqueOpération de réception, unaire, opérateur de réception
SymboleExplicationExemple



&&Logique ET opération. Opérateur binaire et logiquevrai && faux //Le résultat de l'expression est faux
==Opération de jugement d'égalité. Opérateur de comparaison binaire"abc" == "abc" //Le résultat est vrai
!=Opération de jugement inégal. Opérateur de comparaison binaire "abc" != "Abc" //Le résultat est vrai
<moins qu'une opération de jugement. Opérateur de comparaison binaire 1 < 2 //Le résultat de l'expression est vrai
<=inférieur ou égal à. Opérateur de comparaison binaire 1 <= 2 //Le résultat de l'expression est vrai
> est supérieur à l'opération de jugement. Opérateur de comparaison binaire 3 > 2 //Le résultat de l'expression est vrai
>= est supérieur ou égal à. Binaire, opérateur de comparaison 3 >= 2 //Le résultat de l'expression est vrai
+ signifie sommation, unaire est à nouveau binaire, opérateur arithmétique +1 //Le résultat est 1 ( 1+ 2) //Le résultat est 3
- signifie trouver la différence, un yuan équivaut à deux yuans, opérateur arithmétique -1 //Le résultat est -1 (1 – 2) //Le résultat est - 1
Opération OU au niveau du bit, binaire, opérateur arithmétique 5 11 //Le résultat de l'expression est 15
^XOR au niveau du bit, un élément est binaire, opérateur arithmétique 511 //Le résultat est 14 (5)//Le résultat est -6
*Produit ou valeur, unaire, binaire, arithmétique, adresse*p //Opération valeur
/ Opération quotient, opérateur binaire, arithmétique10 / 5 //Le résultat de l'expression est 2
%Opération restante, opérateur binaire, arithmétique12 % 5 //Le résultat de l'expression est 2
<<Opération de décalage à gauche au niveau du bit, binaire, opérateur arithmétique4 << 2 //Le résultat de l'expression est 16
&v //Opération d'adresse &^
5 &^ 11 //Le résultat de l'expression est 4 !
!b //Si b est vrai, le résultat est faux<-
<- ch

注意:假设上面的ch 代表了元素类型为 byte的通道类型值,则<- ch表示从ch中接收byte类型值的操作。

重点讲解3个操作符

1、&^ 实现了按位清除操作,按位清除就是根据第二个操作数的二进制值对第一个操作数的二进制值进行相应的清零操作,如果第二个操作数的某个二进制位上的数组为1,就把第一个操作数的对应二进制位上的数值设置为0。否则,第一个操作数的对应二进制位上的数值不变。这样的操作并不会改变第一个操作数的原值,只会根据两个操作数的二进制值计算出结果值。这样就可以理解上面的5 &^ 11的结果为4了。

2、^ 作为一元操作符,分两种情况:

(1). 操作数是无符号的整数类型,使用这一个操作就相当于对这个操作数和其整数类型的最大值进行二元的按位异或操作,如下:

^uint8(1)           = 254     
//无符号整数的一元按位异或操作00000001 ^ 11111111 = 11111110//对应的二进制数运算1.2.3.
Copier après la connexion

如上,内置函数uint8会将一个整数字面量转换为一个uint8类型的值,这保证了一元操作符^的唯一操作数一定是一个无符号整数类型的值。

(2). 操作是有符号的整数类型,这一操作就相当于对这个操作数和-1进行二元按位异或操作。例如:

^1                  = -2 
//有符号整数的一元按位异或操作00000001 ^ 11111111 = 11111110//对应的二进制运算1.2.
Copier après la connexion

**注意:**以上的操作数的二进制值都是以补码形式表示;默认情况下整数字面量是有符号的,所以(2)中操作数1不需要显示使用内置函数int8 。

3、<- 接收操作符,只作用于通道类型的值。使用时,需要注意两点:

(1). 从一个通道类型的空值(即nil)接收值的表达式将会永远被阻塞。
(2). 从一个已被关闭的通道类型值接收值会永远成功并立即返回一个其元素类型的零值。

一个由接收操作符和通道类型的操作数所组成的表达式可以直接被用于变量赋值或初始化,如下所示(在赋值语句讲解时,再细说)

v1 := <-ch
v2 = <-ch1.2.
Copier après la connexion

特殊标记 = 用于将一个值赋给一个已被声明的变量或常量。
特殊标记 := 则用于在声明一个变量的同时对这个变量进行赋值,且只能在函数体内使用。

又如下:

v, ok = <-ch
v, ok := <-ch1.2.
Copier après la connexion

当同时对两个变量进行赋值或初始化时,第二个变量将会是一个布尔类型的值。这个值代表了接收操作的成功与否。如果这个值为false,就说明这个通道已经被关闭了。(之后讲解通道类型会详细介绍)。

操作符优先级

优先级操作符
5* / % << >> & &^
4+ - \ ^
3== != < <= > >=
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.
Copier après la connexion

如上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.
Copier après la connexion

该表达式的作用是判断“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.
Copier après la connexion

当使用类型断言表达式同时对两个变量进行赋值时,如果类型断言成功,那么赋给第一个变量的将会是已经被转换为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.
Copier après la connexion

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

appendIfAbsent([]string(“A”,”B”,”C”),”C”,”B”,”A”)1.
Copier après la connexion

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

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

appendIfAbsent([]string(“A”,”B”,”C”), []string(”C”,”B”,”A”)...)1.
Copier après la connexion

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

appendIfAbsent([]string(“A”,”B”,”C”), s...)1.
Copier après la connexion

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

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal