表达式、语句和简单语句

此篇文章将简单介绍一下Go语言中的表达式和语句,为后面的(特别是下一篇)文章做一个铺垫。

简单说来,一个表达式表示一个值,而一条语句表示一个操作。 但是在实际中,有些个表达式可能同时表示多个值,有些语句可能是由很多更基本的语句组成的。 另外,根据场合不同,某些语句也可以被视为表达式。

Go中,某些语句被称为简单语句。Go中各种流程控制语句的某些部分可能会被要求必须为简单语句或者表达式。 详见下一篇文章对Go中基本流程控制语句的介绍和解释。

本篇文章将不对表达式和语句作出详尽的解释。 详尽的解释需要大量的篇幅。 本文只是列出一些表达式和语句的例子,并非包括所有的表达式和语句的种类,但是简单语句的所有种类都会被列出来。

一些表达式的例子

Go中大多数的表达式都是单值表达式。一个单值表达式只表示一个值。 某些表达式可以表示多个值,它们被称为多值表达式。

以后(不包括本文),如果没有特殊说明,当表达式这个词被提及的时候,它表示一个单值表达式。

前面的几篇文章介绍的字面量、变量和有名常量等均属于单值表达式。它们可称为基本表达式。

前面的运算操作符一文中介绍的运算符操作(不包括赋值部分)也都属于单值表达式。

如果一个函数至少返回一个值,则它的调用属于表达式。 特别的,如果此函数返回两个或两个以上的值,则对它的调用称为多值表达式。 不返回任何结果的函数的调用不属于表达式。

以后的某篇文章中介绍的方法可以看作是特殊的函数。 所以上述对函数的解释同样适用于方法。

事实上,以后我们将会了解到自定义函数(包括方法)本身都属于函数类型的值,所以它们都是单值表达式。

通道的接收数据操作(不包括赋值部分)也属于表达式。通道将在以后详解。

Go中的一些表达式,包括刚提及的通道的接收数据操作,可能会表示可变数量的值。 根据不同的场景,这样的表达式可能呈现为单值表达式,也可能呈现为多值表达式。 我们将在以后的文章中了解到这样的表达式。

简单语句类型列表

Go中有六种简单语句类型:

  1. 变量短声明语句。
  2. 纯赋值语句,包括x op= y这种运算形式。
  3. 有返回结果的函数或方法调用,以及通道的接收数据操作。 上一节已经提到了,这些语句也可以用做表达式。
  4. 通道的发送数据操作。上面已经提到过一次,通道以后将在此文中详解。
  5. 空语句。在下一篇文章我们将看到一些空语句的应用。
  6. 自增(x++)和自减(x--)语句。

注意:和C/C++不一样,在Go中,自增和自减语句不能被当作表达式使用。

简单语句这个概念在Go中比较重要,所以请牢记这六种简单语句类型。

一些非简单语句

下面是一个非简单语句的不完整列表:

  • 标准变量声明语句。是的,短声明语句属于简单语句,但是标准变量声明语句不属于。
  • (有名)常量声明语句。
  • 类型声明语句。
  • (代码)包引入语句。
  • 显式代码块。一个显式代码块起始于一个左大括号{,终止于一个右大括号}。 一个显式代码块中可以包含若干子语句。
  • 函数声明。 一个函数声明中可以包含若干子语句。
  • 流程控制跳转语句。详见下一章。
  • 函数返回(return)语句。
  • 延迟函数调用和协程创建语句。下下篇文章将会介绍。

一些表达式和语句的例子

  1. // 一些非简单语句:
  2. import "time"
  3. var a = 123
  4. const B = "Go"
  5. type Choice bool
  6. func f() int {
  7. for a < 10 {
  8. break
  9. }
  10. // 这是一个显式代码块。
  11. {
  12. // ...
  13. }
  14. return 567
  15. }
  16. // 一些简单语句的例子:
  17. c := make(chan bool) // 通道将在以后讲解
  18. a = 789
  19. a += 5
  20. a = f() // 这是一个纯赋值语句
  21. a++
  22. a--
  23. c <- true // 一个通道发送操作
  24. z := <-c // 一个使用通道接收操作
  25. // 做为源值的变量短声明语句
  26. // 一些表达式的例子:
  27. 123
  28. true
  29. B
  30. B + " language"
  31. a - 789
  32. a > 0 // 一个类型不确定布尔值
  33. f // 一个类型为“func ()”的表达式
  34. // 下面这些即可以被视为简单语句,也可以被视为表达式。
  35. f() // 函数调用
  36. <-c // 通道接收操作