• 【Go入门教程2】基本构成元素:标识符(identifier)、关键字(keyword 25个)、字面量(literal)、分隔符(delimiter)、和 操作符(operator)


    基本构成要素

    Go 的语言符号 又称 词法元素,共包括 5 类内容——标识符(identifier)、关键字(keyword)、字面量(literal)、分隔符(delimiter) 和 操作符(operator),它们可以组成各种表达式 和 语句,而后者都无需以分号结尾。

    标识符

    标识符可以表示 程序实体,前者即为后者的名称。在一般情况下,同一个代码块中不允许出现同名的程序实体。使用不同代码包中的程序实体需要用到限定标识符,比如:os.O_RDONLY。

    另外,Go 中还存在着一些特殊的标识符,叫作预定义标识符,它们在 Go 源码中声明的。这类标识符包括以下几种。

    • 所有基本数据类型的名称
    • 接口类型 error
    • 常量 true、false 和 iota。

    所有的 内建函数 的名称,即 append、cap、close、complex、copy、delete、imag、len、make、new、panic、print、println、real 和 recover。

    这里强调一下 空标识符,它由一个下划线 _ 表示,一般用在变量声明 或 代码包 导入语句中。若在代码中存在一个变量 x,但是却不存在任何对它的使用,则编译器会报错。如果在变量 x 的声明代码后添加这样一行代码:

    _ = x

    就可以绕过编译器检查,使它不产生任何编译错误。这是因为这段代码确实用到了变量 x,只不过它没有在变量 x 上进行任何操作,也没有将它赋值给任何其他变量。空标识符就像一个垃圾桶。在相关初始化工作完成后,操作对象就会被弃之不用。

    关键字

    关键字 是被编程语言保留的字符序列,编程人员不能把它们用作标识符。因此,关键字也称为 保留字

    Go 的关键字可以分为 3 类,包括用于 程序声明的关键字、用于程序实体声明 和 定义 的关键字,以及用于程序流程控制的关键字,如下图所示:

    类 别关 键 字
    程序声明 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 关键字共有 25 个,其中与并发编程有关的关键字有 go、chan 和 select。

    这里特别说明一下关键字 type 的用途——类型声明。我们可以使用它声明一个 自定义类型:

    type myString string

    这里把名为 myString 的类型声明为 string 类型的一个别名类型。反过来说,string 类型是 myString 类型的 潜在类型。再看另一个例子,基本类型 rune 是 int32 类型的一个别名类型。int32 类型就是 rune 类型的潜在类型。虽然类型及其潜在类型是不同的 两个 类型,但是它们的值可以进行类型转换,例如:string(myString("ABC"))。这样的类型转换不会产生新值,几乎没什么代价。

    自定义的类型一般都会基于 Go 中一个或多个预定义类型,就像上面的 myString 和 string 那样。如果为自定义类型关联若干方法(函数的变体),那么还可以让它成为某个或某些接口类型的实现类型。另外,还有一个比较特殊的类型,叫 空接口。它的类型字面量是 interface{}。在 Go 语言中,任何类型都是 空接口 类型的实现类型。

    字面量

    简单来说,字面量就是 的一种 标记法。但是,在 Go 中,字面量的含义要更加广泛一些。我们常常用到的字面量有以下 3 类。

    1、用于表示基础数据类型 的各种字面量。这是最常用的一类字面量,例如,表示浮点数类型值的 12E-3

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

    type Name struct {
        Forename    string
        Surname     string
    }

    3、用于表示复合数据类型的 的复合字面量,它可以用来构造 struct(结构体)、array(数组)、slice(切边) 和 map(字典) 类型的值。复合字面量 一般由字面类型 以及 被花括号包裹的复合元素的列表组成。字面类型 指的就是 复合数据类型 的名称。

    例如,下面的复合字面量构造出了一个 Name 类型的值:

    Name{Forename: "Robert", Surname: "Hao"}

    其中 Name 表示这个值的类型,紧随其后的就是由键值对表示的复合元素列表。

    操作符

    操作符,也称 运算符。它是用于执行特定算术 或 逻辑操作的符号,操作的对象称为 操作数。Go 有如下操作符:

    符 号说 明示 例
    || 逻辑或操作,二元操作符,逻辑操作符 true || false // 结果为 true
    && 逻辑与操作,二元操作符,逻辑操作符 true && false // 结果为 false
    == 相等判断操作,二元操作符,比较操作符 "abc" == "abc" // 结果为 true
    != 不等判断操作,二元操作符,比较操作符 "abc" != "Abc" // 结果为 true
    < 小于判断操作,二元操作符,比较操作符 1 < 2 // 结果为 true
    <= 小于或等于判断操作,二元操作符,比较操作符 1 <= 2 // 结果为 true
    > 大于判断操作,二元操作符,比较操作符 3 > 2 // 结果为 true
    >= 大于或等于操作判断,二元操作符,比较操作符 3 >= 2 // 结果为 true
    + 求和操作,一元操作符,二元操作符,算术操作符。若为一元操作符,不会对原值产生任何影响 +1 // 结果为 1
    1 + 2 // 结果为 3
    - 求差操作,一元操作符,二元操作符,算术操作符。若为一元操作符,则表示求反操作。 -1 // 结果为 -1(1的相反数)
    1 - 3 // 结果为 -2
    | 按位或操作,二元操作符,算术操作符 5 | 11 // 结果为 15
    ^ 按位异或操作,一元操作符,二元操作符,算术操作符。若为一元操作符,则表示按位补码操作。 5 ^ 11 // 结果为 14
    ^5 // 结果为 -6
    * 求乘操作,一元操作符,二元操作符,算术操作符,地址操作符。若为地址操作符,则表示取值操作 *p // 若 p 为指向整数类型值 2 的指针类型值,则结果为 2
    2 * 5 // 结果为 10
    / 求商操作,二元操作符,算术操作符 10 / 5 // 结果为 2
    % 求余数操作,二元操作符,算术操作符 12 % 5 // 结果为 2
    << 按位左移操作,二元操作符,算术操作符 4 << 2 // 结果为 16
    >> 按位右移操作,二元操作符,算术操作符 4 >> 2 // 结果为 1
    & 按位与操作,一元操作符,二元操作符,算术操作符,地址操作符,则表示取址操作 &v // 结果为标识符 v 所代表的值在内存中的地址
    5 & 11 // 结果为 1
    &^ 按位清除操作,二元操作符,算术操作符 5 &^ 11 // 结果为 4
    ! 逻辑非操作,一元操作符,逻辑操作符 !b // 若 b 的值为 false,则表达式的结果为 true
    <- 接收操作,一元操作符,接收操作符 <- ch // 若 ch 代表了元素类型为 byte 的通道类型值,则此表达式就表示从 ch 中接收一个 byte 类型值的操作

    Go 的操作符一共有 21 个,并分为 5 类:算术操作符、比较操作符、逻辑操作符、地址操作符 和 接收操作符。

    当一个表达式中存在多个操作符时,就涉及操作顺序的问题。在 Go 中,一元操作符拥有最高的优先级,而二元操作符的优先级如下表所示:

    优 先 级
    (数字越大,优先级越高)
    操 作 符
    5 *、/、%、<<、>>、&、&^
    4 +、-、|、^
    3 ==、!=、<、<=、>、>=
    2 &&
    1 ||

    如果在一个表达式中出现了处于相同优先级的多个操作符,且这些操作符之间存在操作数,那么就会按照从左到右的顺序进行操作。当然,我们可以使用圆括号显示地改变原有的操作顺序,例如表达式 a << (4 * b) & c 等同于 (a << (4 * b)) & c,即子表达式 4 * b 会先被求值。

    最后需要注意的是,++ 和 -- 是语句,而不是表达式,因而他们不存在于任何操作优先级层次之内。例如 表达式 *p-- 等同于 (*p)--

    表达式

    表达式 是把 操作符 和 函数 作用于操作数的计算方法。在 Go 中,表达式 是构成具有词法意义的代码的最基本元素。Go 的表达式有很多种,具体如下表所示:

    种 类用 途示例
    选择表达式 选择一个值中的字段或方法 context.Speaker // context 是变量名
    索引表达式 选取数组、切片、字符串 或 字典值 中的某个元素 array1[1] // array1 表示一个数组值,其长度必须大于 1
    切片表达式 选取数组、数组指针、切片 或 字符串值中的某个范围的元素 slice[0:2] // slice1 表示一个切片值,其容量必须大于 或 等于 2
    类型断言 判断一个接口值的实际类型是否为某个类型,或一个非接口值的类型是否实现了某个接口类型 v1.(I1) // v1 表示一个接口值,I1 表示一个接口类型
    调用表达式 调用一个函数 或 一个值的方法 v1.M1() // v1 表示一个值,M1 表示与该值关联的一个方法

    关于 类型断言,有 2 点需要注意一下:

    1、如果 v1 是一个非接口值,那么必须在做类型断言之前把它转换成 接口值

    因为 Go 中的任何类型都是 空接口类型 的实现类型,所以一般会这样做:interface{}(v1).(I1)

    2、如果类型断言的结果为否,就意味着该类型断言是失败的。失败的类型断言会引发一个运行时恐慌(或称运行时异常),解决方法是:

    var i1, ok = interface{}(v1).(I1)

    这里声明并赋值了 2 个变量,其中 ok 是布尔类型的变量,它的值体现了类型断言的成败。如果成功,i1 就会是经过类型转换后的 I1 类型的值,否则它将会是 I1 类型的零值(或称默认值)。如此一来,当类型断言失败时,运行时恐慌就不会发生。

    关键字 var 用于变量的声明。在它 和 等号(=) 之间可以有多个由逗号(,)隔开的变量名。这种在一条语句中同时为多个变量赋值的方式叫 平行赋值。另外,如果在声明变量的同时进行赋值,那么等号左边的变量类型可以省略。如果不使用上述几个技巧的话,上面那条语句可以写成:

    var i1 I1
    var ok bool
    i1, ok = interface{}(v1).(I1)

    另一方面,上面那条语句还可以简写成:

    i1, ok := interface{}(v1).(I1)

    这种简写方式只能出现在函数中。有了符号 :=,关键字 var 也可以省略了,这叫 短变量声明

    摘自:《Go并发编程实战(第2版)》

  • 相关阅读:
    分页存储过程
    调存储过程
    winform httplicent调用API
    存储过程,触发器,等等。。。
    C# AJAXform上传图片
    Mysql order by与limit联用出现的问题
    将Sublime Text 3 放到右键中
    Vue-cli构建步骤
    Javascript面试知识点
    position详解
  • 原文地址:https://www.cnblogs.com/52php/p/6884935.html
Copyright © 2020-2023  润新知