Go Again

前看过一次GoTour,不过第一次看的是英文版的,看完就忘了,这次再看一遍中文版来巩固一下。

在Go中,一个变量名以大写字母开头则为以导出的。否则为未导出的。例如:math.Pi

Go中支持多值返回,可以返回任意数量的返回值。

声明变量通过var关键字,如果不用该关键字则需使用:=赋值运算符。函数外的每个语句都必须以关键字开始,因此该运算符不能在函数外使用。

零值:没有明确初始化值的变量声明。数值类型:0,布尔类型:false,字符串:""(空字符串)。

常量赋值使用const关键字,并且不能使用:=赋值符号。常量会自动推断类型。

循环

Go中只有for循环。该循环类似于C语言中的for循环,区别在于后面不用跟小括号,而大括号是必须的(不管是只有一条语句还是多条)。这三条语句都是可选的(即初始化语句、条件判断语句和后置语句),所以如果你怀恋while语句则可以通过省略1、3条语句,只写第二条语句(即条件判断语句)来实现Go中的while循环。你也可以通过如下形式来实现Go中的无限循环:

package main

import "fmt"

func main() {
	for {
		fmt.Println("hello world!")
	}
}

条件判断语句

  • if

    if语句表达式无需加小括号,但是执行内容必须通过大括号包裹起来。

    if语句可以在条件表达式执行之前执行一个简单语句,该语句声明的变量作用域仅在if之内。例如:

    package main
    
    import "fmt"
    
    func main() {
      if x := 2; x < 3 {
          fmt.Println("x小于3!") // x小于3!
      }
      fmt.Println(x) // undefined: x
    }
    
  • switch

    switch语句本质上就是一连串的if - else语句。该语句可比C语言中的switch语句好太多了:

    • Go会默认为每个case语句最后添加break语句,这意味着不需要我们手动写break了(除非以fallthrough语句结束)。
    • Go中switch 的 case 无需为常量,且取值不必为整数。
  • defer

    • defer语句会将函数推迟到该语句所在的函数返回之后再执行。defer后的函数的参数会立即求值,但是只有到外层函数返回后才会被调用。
    • 推迟的函数调用会被压入一个栈中。当外层函数返回时,被推迟的函数会按照后进先出的顺序调用。

指针

Go有指针,但没有指针运算。

切片

  • 类似于python,Go也有自己的切片。切片中可传入两个参数,开头和结尾,以冒号分隔。包括开头但不包括结尾;两个参数都是可以省略的,第一个参数省略则默认为0,第二个参数省略则默认为数组的长度。例如:
package main

import "fmt"

func main() {
	primes := [6]int{2, 3, 5, 7, 11, 13}

	var s []int = primes[1:4]
	fmt.Println(s) // [3 5 7]
}
  • 注意Go中数组打印出来是以空格分隔的,而不是分号。

  • 切片就像是数组的引用,如果我们修改了切片中的元素,那么会修改原数组相应的值。

  • 切片拥有长度和容量(length, capcity)。切片的长度就是它所包含的元素个数。切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。底层数组就是切片所引用的数组。切片 s 的长度和容量可通过表达式 len(s)cap(s) 来获取。

    nil 切片

    当我们只声明了一个数组或切片而未给其赋值,则其默认为零值

    切片的零值是 nil

    nil 切片的长度和容量为 0 且没有底层数组。