1. Go语言组成

    • 包声明
    • 引入包
    • 函数
    • 变量(当标识符(包括变量,常量类型,函数名结构字段等等)以一个大写字母开头时,可以被外部调用,称为导出)
    • 语句&表达式
    • 注释
  2. 在Go程序中,一个语句以一行分隔,而C语言家族使用分号;隔开.

  3. 标识符用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(A~Z和a~z)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字。

  4. go代码中会使用的25个关键字或保留字:

    breakdefaultfuncinterfaceselectcasedefer
    gomapstructchanelsegotopackage
    switchconstfallthroughifrangetypecontinue
    forimportreturnvar
  5. Go语言的36个预定义标识符:

    appendboolbytecapclosecomplexcomplex64complex128uint16
    copyfalsefloat32float64imagintint8int16uint32
    int32int64iotalenmakenewnilpanicuint64
    printprintlnrealrecoverstringtrueuintuint8uintptr
  6. go语言的字符串是由单个字节连接起来的.go语言使用的是UTF-8编码的Unicode文本

  7. 可以省略var定义关键字,而是使用类似c:=123形式,注意 :=左侧的变量不应该是已经声明过的,否则会导致编译错误。这是使用变量的首选形式,但是它只能被用在函数体内,而不可以用于全局变量的声明与赋值。

  8. 如果你声明了一个局部变量却没有在相同的代码块中使用它,同样会得到编译错误,如下:

    1
    2
    3
    4
    
    func main() {
    var a string = "abc"
    fmt.Println("hello, world")
    } # a declared and not used
    

    ``

  9. 如果你想要交换两个变量的值,则可以简单地使用 a, b = b, a。

  10. 空白标识符 _ 也被用于抛弃值,如值 5 在:_, b = 5, 7 中被抛弃。 _ 实际上是一个只写变量,你不能得到它的值。这样做是因为 Go 语言中你必须使用所有被声明的变量,但有时你并不需要使用从一个函数得到的所有返回值。

  11. 并行赋值也被用于当一个函数返回多个返回值时,比如这里的 val 和错误 err 是通过调用 Func1 函数同时得到:val, err = Func1(var1)

  12. Go语言常量数据类型只可以是布尔型、数字型和字符串型。

  13. iota,特殊变量,可以被修改器修改。在每一个const关键字出现时,被置为0,然后再下一个const出现前,每一次iota,其所代表的数字会自动加1.iota可以用于迭代器

  14. Go语言运算符:

    • 算术运算符:+,-,*,/,%,++,–
    • 关系运算符:==,!=,>,<,>=,<=
    • 逻辑运算符:&&,||,!
    • 位运算符:&,|,^,«,»
    • 赋值运算符:=,+=,-=,*=,/=,%=,«=,»=,&=,^=,|=
    • 其他运算符: &(返回变量存储地址),*(指针变量)
  15. 位运算符详细说明:(A=0011 1100;B=0000 1101)

    运算符描述实例
    &按位与运算符"&“是双目运算符。 其功能是参与运算的两数各对应的二进位相与。(A & B) 结果为 12, 二进制为 0000 1100
    \|按位或运算符”\|“是双目运算符。 其功能是参与运算的两数各对应的二进位相或A
    ^按位异或运算符”^“是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。(A ^ B) 结果为 49, 二进制为 0011 0001
    «左移运算符”«“是双目运算符。左移n位就是乘以2的n次方。 其功能把”«“左边的运算数的各二进位全部左移若干位,由”«“右边的数指定移动的位数,高位丢弃,低位补0。A « 2 结果为 240 ,二进制为 1111 0000
    >>右移运算符”»“是双目运算符。右移n位就是除以2的n次方。 其功能是把”»“左边的运算数的各二进位全部右移若干位,"»“右边的数指定移动的位数。A » 2 结果为 15 ,二进制为 0000 1111
  16. 运算符优先级:

    优先级运算符
    7^ !
    6* / % « » & &^
    5+ - \| ^
    4== != < <= >= >
    3<-
    2&&
    1\|\
  17. select语句:每个case都必须是一个通信;所有channel表达式都会被求值;所有被发送的表达式都会被求值;如果任意某个通信可以进行,它就执行;其他被忽略。如果有多个case都可以运行,Select会随机公平地选出一个执行。其他不会执行。 否则: 14. 如果有default子句,则执行该语句。 15. 如果没有default字句,select将阻塞,直到某个通信可以运行;Go不会重新对channel或值进行求值。

  18. Go 语言的 goto 语句可以无条件地转移到过程中指定的行。goto语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能,但是,在结构化程序设计中一般不主张使用goto语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。

  19. 引用传递,例子:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    
    package main
    
    import "fmt"
    
    func main() {
       /* 定义局部变量 */
       var a int = 100
       var b int= 200
    
       fmt.Printf("交换前,a 的值 : %d\n", a )
       fmt.Printf("交换前,b 的值 : %d\n", b )
    
       /* 调用 swap() 函数
       * &a 指向 a 指针,a 变量的地址
       * &b 指向 b 指针,b 变量的地址
       */
       swap(&a, &b)
    
       fmt.Printf("交换后,a 的值 : %d\n", a )
       fmt.Printf("交换后,b 的值 : %d\n", b )
    }
    
    func swap(x *int, y *int) {
       var temp int
       temp = *x    /* 保存 x 地址上的值 */
       *x = *y      /* 将 y 值赋给 x */
       *y = temp    /* 将 temp 值赋给 y */
    }
    
  20. 函数做为值

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    
    package main
    
    import (
    	"fmt"
    	"math"
    )
    
    func main() {
    	getSquareRoot := func(x float64) float64 {
            return math.Sqrt(x)
    	}
    	fmt.Println(getSquareRoot(9))
    
    }
    
  21. 闭包操作(Go 语言支持匿名函数,可作为闭包。匿名函数是一个"内联"语句或表达式。匿名函数的优越性在于可以直接使用函数内的变量,不必申明。):

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    package main
    import (
    	"fmt"
    )
    func getSequence() func() int {
    	i := 0
    	return func() int {
            i++
            return i
    	}
    }
    func main()  {
    	nextNumber := getSequence()
    	fmt.Println(nextNumber())
    	fmt.Println(nextNumber())
    	fmt.Println(nextNumber())
    	nextNumber1 := getSequence()
    	fmt.Println(nextNumber1())
    	fmt.Println(nextNumber1())
    }
    
  22. Go 语言中同时有函数和方法。一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。所有给定类型的方法属于该类型的方法集。语法格式如下:

    1
    2
    3
    
    func (variable_name variable_data_type) function_name() [return_type]{
       /* 函数体*/
    }
    

    example:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    // method_statement.go
    
    package main
    
    import (
    	"fmt"
    )
    
    type Circle struct {
    	radius float64
    }
    
    func main() {
    	var c1 Circle
    	c1.radius = 10.00
    	fmt.Println("Area of Circle(c1) = ", c1.getArea())
    }
    
    func (c Circle) getArea() float64 {
    	return 3.14 * c.radius * c.radius
    }
    //result:Area of Circle(c1) =  314
    
  23. Go 语言程序中全局变量与局部变量名称可以相同,但是函数内的局部变量会被优先考虑。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    // local_global_var.go
    
    package main
    
    import (
    	"fmt"
    )
    
    var b string = "Golang"
    
    func main() {
    	var a string = "lryong"
    	var b string = "future" //函数内的局部变量会被优先考虑
    	fmt.Printf("a is %s,b is %s\n", a, b)
    }
    
  24. 数组初始化:var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

  25. 多维数组:var threedim [5][10][4]int

  26. Go空指针:当一个指针被定义后没有分配到任何变量时,它的值为 nil。nil 指针也称为空指针。nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。一个指针变量通常缩写为 ptr。

    • example:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    // nil_pointer.go
    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	var ptr *int
    	/*空指针判断*/
    	if ptr == nil { //ptr空指针
            fmt.Println("Has not assigned pointer")
    	} else {
            fmt.Println("Has assigned pointer")
    	}
    	fmt.Printf("ptr's value is %d\n", ptr) //空指针
    }
    
  27. 指针数组:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    // pointer_array.go
    package main
    
    import (
    	"fmt"
    )
    
    const MAX int = 3
    
    func main() {
    	var a = [3]int{10, 100, 1000}
    	var ptr [MAX]*int
    	for i := 0; i < MAX; i++ {
            ptr[i] = &a[i] //整数地址赋值给指针数组
    	}
    
    	for i := 0; i < MAX; i++ {
            fmt.Printf("a[%d] = %d\n", i, *ptr[i])
    	}
    
    }
    
  28. 指向指针的指针:var ptr **int

    • example:
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      
      // pointer_to_pointer.go
      package main
      
      import (
          
      )
      
      func main() {
           int
          tr *int
          ptr **int
      
          55
           &a
          = &ptr
      
          rintf("变量a = %d\n", a)
          rintf("指针变量*ptr = %d\n", *ptr)
          rintf("指针变量**ptr = %d\n", **pptr)
      }
      
  29. Go语言指针作为函数参数,Go 语言允许向函数传递指针,只需要在函数定义的参数上设置为指针类型即可。