Go 言語にはいくつかの種類の語彙要素があります

青灯夜游
リリース: 2023-01-12 10:03:16
オリジナル
1753 人が閲覧しました

Go 言語には 5 種類の語彙要素があります: 1. 識別子 (Unicode でエンコードされた) の多数の文字、アンダースコア、数字で構成される文字シーケンス; 2. キーワード (によって予約されています)プログラマが識別子として使用することを許可されていない文字シーケンスも予約語と呼ばれます; 3. 演算子は特定の算術演算または論理演算を実行するために使用される記号です; 4. 区切り文字; 5. リテラル (値)表記です。

Go 言語にはいくつかの種類の語彙要素があります

このチュートリアルの動作環境: Windows 7 システム、GO バージョン 1.18、Dell G3 コンピューター。

Go 言語の言語シンボルは語彙要素とも呼ばれ、識別子、キーワード、演算子、区切り文字、リテラルの 5 つのカテゴリが含まれます。 は、Go を構成する最も基本的な単位です。言語コードとプログラム。

一般に、スペース、水平タブ、キャリッジ リターン、ライン フィードは、複数の言語記号の間の区切り文字の一部として使用されない限り無視されます。 Go 言語では、明示的にセミコロンを挿入する必要はなく、必要に応じて、Go 言語はステートメントを区切るためにコードにセミコロンを自動的に挿入します。

Go 言語のコードは、複数の Unicode 文字で構成されています。Go 言語のすべてのソース コードは、Unicode エンコード仕様の UTF-8 エンコード形式でエンコードされる必要があります (つまり、記述された Go 言語のソース コード)ファイルは UTF-8 エンコード形式である必要があります)。

Go 言語の言語シンボルは字句要素とも呼ばれ、identifier (識別子)、keyword (キーワード)、操作文字 # の 5 つのカテゴリが含まれます。 ## (演算子)、区切り文字 (区切り文字)、および リテラル (リテラル)。一般に、スペース、水平タブ、キャリッジ リターン、およびライン フィードは、複数の言語記号の間の区切り文字の一部として使用されない限り無視されます。 Go 言語では、明示的にセミコロンを挿入する必要はなく、必要に応じて、Go 言語はステートメントを区切るためにコードにセミコロンを自動的に挿入します。

Go 言語のコードは、複数の Unicode 文字で構成されています。Go 言語のすべてのソース コードは、Unicode エンコード仕様の UTF-8 エンコード形式でエンコードされる必要があります (つまり、記述された Go 言語のソース コード)ファイルは UTF-8 エンコード形式である必要があります)。

1. 識別子

Go 言語の識別子は、複数の文字 (Unicode でエンコードされた)、アンダースコア、数字で構成される文字列であり、この文字列の最初の文字がof は文字でなければなりません。

注:

  • Go 言語コードでは、すべての識別子を使用前に宣言する必要があります。

  • 宣言は、空ではない識別子を定数、型、変数、関数、またはコード パッケージにバインドします。

  • 同じコード ブロック内で、同じ識別子の繰り返しの宣言は許可されません (代入ステートメントを除く)。

  • ソース コード ファイルとコード パッケージ内の識別子は、このルールに従う必要があります。

  • 宣言された識別子のスコープは、それが直接属するコード ブロックのスコープと同じです。

厳密に言えば、コード パッケージ宣言ステートメントはステートメントではありません。コード パッケージ名がどのスコープにも表示されないためです。コード パッケージ宣言ステートメントの目的は、複数のソース コード ファイルが同じコード パッケージに属しているかどうかを識別すること、またはコード パッケージをインポートするときにデフォルトのコード パッケージ参照名を指定することです。

修飾識別子は、他のコード パッケージ内の変数または型にアクセスするために使用されます。たとえば、コード パッケージ os 内の O_RDONLY という名前の定数にアクセスする必要がある場合、次のように os.O_RDONLY を記述する必要があります。

修飾識別子を使用でき、次の 2 つの前提条件を満たす必要があります:

  • アクセスするコード パッケージは事前にインポートする必要があります;

  • このコード パッケージ内の識別子はエクスポート可能である必要があります。

エクスポート可能な識別子は、次の 2 つの前提条件も満たしている必要があります。

  • 識別子の名前の最初の文字は大文字である必要があります (Go 言語によってアクセスが決定されます)識別子の名前の最初の文字の大文字と小文字に基づいて、この識別子のアクセス許可が決まります。識別子の名前の最初の文字が大文字の場合、そのアクセス許可は「パブリック」です。つまり、識別子には、任意のコード パッケージ内の任意のコードからアクセスできます。修飾された識別子を通じて、識別子の最初の文字が小文字の場合、そのアクセス許可は「パッケージ レベルのプライベート」、つまり識別子と同じ識別子のみにアクセスされます。コード パッケージ内のコードによってのみアクセスできます。 );

  • 識別子は、コード パッケージで宣言された変数または型の名前であるか、構造体の型のフィールド名またはメソッド名に属している必要があります。

Go 言語の事前定義された識別子:

  • すべての基本データ型の名前。
  • インターフェイス タイプ エラー
  • 定数 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. キーワード

キーワード (予約語とも呼ばれます) はプログラミング言語によって予約されており、プログラマが識別子として使用するものではありません。使用する文字シーケンス。

##プログラムエンティティの宣言と定義プログラム制御フロー

在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 の潜在的な型文字列であることがわかります。

Go 言語では、配列型の潜在的な型によって、その型の変数にどの型の要素を格納できるかが決まると規定されています。

5. 演算子

演算子は、特定の算術演算または論理演算を実行するために使用される記号です。 (C言語の演算子と似ているのでここでは詳しく説明しません) ただし、Go言語には三項演算子がないため、単項演算子を除いてすべての演算子は二項演算子でなければなりません。 Go言語には算術演算子、比較演算子、論理演算子、アドレス演算子、受付演算子など合計21個の演算子があります。

カテゴリキーワード
プログラム ステートメントインポート、package
##chan、const、func、interface、map、struct、type、var
go、select、break、case、 continue、default、defer、else、fallthrough、for、goto、if、range、return、switch
#シンボル説明例&&&==#!=##< は判定演算より小さい。バイナリ、比較演算子 1 < 2 //式の結果は true です。<= は以下です。バイナリ、比較演算子 1 <= 2 //式の結果は true です。> は判定演算よりも大きいです。バイナリ、比較演算子 3 > 2 //式の結果は true です>= は以上です。バイナリ、比較演算子 3 >= 2 //式の結果は true # は合計、1 元は 2 元、算術を意味します演算子 1 //結果は 1 (1 2) //結果は 3- は差を表し、1 元です再びバイナリです。算術演算子 -1 //結果は -1 (1 – 2) //結果は -1\# です##ビットごとの OR 演算、バイナリ、算術演算子 ビット XOR を押してください、1 つの要素はバイナリ、算術演算子 11//結果は 14 ( 製品または値、1 元、2 バイナリ、算術、アドレス商演算、バイナリ、算術演算子剰余演算、バイナリ、算術演算子ビット単位の左シフト演算、バイナリ、算術演算演算子##>>ビット単位の右シフト演算、バイナリ、算術演算子4 >> 2 //式の結果は1&v //アドレス演算5 &^ 11 //式の結果は 4!b //If bは true、結果は false##<-受信操作、単項、受信演算子<- ch

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

重点讲解3个操作符

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

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

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

^uint8(1)           = 254     
//无符号整数的一元按位异或操作00000001 ^ 11111111 = 11111110//对应的二进制数运算1.2.3.
ログイン後にコピー

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

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

^1                  = -2 
//有符号整数的一元按位异或操作00000001 ^ 11111111 = 11111110//对应的二进制运算1.2.
ログイン後にコピー

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

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

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

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

v1 := <-ch
v2 = <-ch1.2.
ログイン後にコピー

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

又如下:

v, ok = <-ch
v, ok := <-ch1.2.
ログイン後にコピー

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

操作符优先级




ロジックと操作。二項論理演算子 true && false //式の結果は false です
等価判定演算です。バイナリ、比較演算子 "abc" == "abc" //結果は true
不等判定演算。バイナリ、比較演算子 "abc" != "Abc" //結果は true
5 \ 11 //式の結果は 15^
55)//結果は -6 *
*p //値演算/
10 / 5 //式の結果は2%
12 % 5 //式の結果は2<<
4 << 2 //式の結果は16
##& ビット単位のAND演算、単項、二項、算術, address
&^# #ビット単位のクリア演算、バイナリ、算術演算子
! 論理演算非演算、単項論理演算子
优先级操作符
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.
ログイン後にコピー

如上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 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!