一.go开发工具vscode安装以及扩展安装说明(只介绍关键点,其它可以自行google)
  • click me to download Visual Studio Code
  • click me to install go extension
  • go downloads
  • 在进行扩展安装时 因为GFW的原因,多个扩展会提示安装失败,会导致我们进行开发的时候很是不方便。
  • vscode_plugin_fail

  • 可以手动进行安装下:

    • go get -u -v github.com/nsf/gocode
    • go get -u -v github.com/rogpeppe/godef
    • go get -u -v github.com/lukehoban/go-outline
    • go get -u -v github.com/tpng/gopkgs
    • go get -u -v github.com/newhook/go-symbols
    • go get -u -v github.com/derekparker/delve/cmd/dlv
  • vscode extension 离线安装方法

  • 依旧有小部分插件无法安装成功,这里我已经去掉了,不影响整体使用。
二.go语言特性
  • 2.1 垃圾回收

    • 内存自动回收,再也不需要开发人员管理内存。
    • 只需要new分配内存,不需要释放。
  • 2.2 天然并发

    • 从语言层面支持并发,非常简单。
    • goroute,轻量级线程,创建成千上万个goroute成为可能。
    • 基于CSP(Communicating Sequential Process)模型实现。
    • CSP模型学习了解-待学习。
    • 每个goroute可以理解为一个最小的基本单元,一个轻量级线程,每个goroute互相独立。
  • 2.3 goroute多线程简例:

test.go ``` package main

import ( "fmt" )

func testGoroute(a int, b int) { sum := a + b fmt.Println(sum) }

func testPrint(a int) { fmt.Println(a) }


> hello.go

package main

import ( "time" )

func main() {

  for i := 0; i < 10; i++ {
      go testPrint(i)
  }
  // 如果不添加sleep 会导致主进程执行完毕关闭,子进程还未执行的情况,导致看不到结果数据。
  time.Sleep(5 * time.Second)

}


* 执行结果如下 可以看到结果输出并不是串行 而是并行操作。
* ![goroute_example1_pic](../image/goroute_example1.png)

* 2.4 channel
  * 管道,类似Unix/Linux中的pipe。
  * 多个goroute之间通过channel进行通信,不能A goroute直接去访问B goroute里面的变量。
  * 支持任何类似。
  * 每个进程都是相互独立的,进程与进程之间默认是不能相互通信的。
  * 假如两个进程,一个进程处理账号,一个进程处理账号里面的钱,两个进程需要通信,但是两个进程都是相互独立隔离的,不能进行数据交互,这时候可以使用channel,A进程把数据放入channel,B进程就去channel去取数据。
  * channel是操作系统支持的。


* channel 示例:

> pipe.go

package main

import "fmt"

func testPipe() {

pipe := make(chan int, 3) //定义一个管道 整型 长度为3
pipe <- 1 // 将 1 2 3 放入管道
pipe <- 2
pipe <- 3

//测试多加一个数据 会产生如下死锁情况,但是放在管道里 不会阻塞会继续执行。  
      可以将代码里的testPipe() 变更为go testPipe()测试,前后加入数据打印,具体的如如下注释部分。

//pipe <- 4
/*
    go run .\hello.go .\pipe.go
    fatal error: all goroutines are asleep - deadlock!

    goroutine 1 [chan send]:
    main.testPipe()
    D:/code/go/src/day1/pipe.go:12 +0xae
    main.main()
    D:/code/go/src/day1/hello.go:25 +0x27
    exit status 2
*/


var t1 int  //将数据从管道取出来 定义如下
t1 =<- pipe
pipe <- 4

fmt.Println(t1)

// print length
fmt.Println(len(pipe))

}


> hello.go
```go
package main

func main() {
    // 主函数调用管道
    //fmt.Println("start goroute")
    testPipe()
    //go testPipe()
    //fmt.Println("end goroute")
    //time.Sleep(10 * time.Second)

}
  • 示意图如下 channel为先进先出模式
  • goroute_example1_pic

  • 2.5 变量语法引用

    • 大写可被外部引用,小写不可被外部引用。
  • 2.5 包的概念

    • 和Python一样,把相同功能的代码放到一个目录,称之为包。
    • 包可以被其它包引用。
    • main包是用来生产可执行文件,每个程序只有一个main包。
    • 包的主要用途是提高代码的可重复性。
    • 同一个包里有且只有一个main函数,多的话会直接报错。
    • go编译完成后只有一个可执行文件。
    • go 目录组织方式
      • D:\project
      • src 存放源码文件的位置。
      • bin 存放编译后文件的位置。
      • pkg 存放编译完毕后文件的静态库 比如go install之后生产的静态库.
      • vender
    • WIN -> GOPATH=D:/project
    • Linux -> export GOPATH=d:/project
    • D:\project\src\go_dev\day1\example1

    • go 编译的时候 可以直接在 GOPATH下执行 然后会生成example1.exe文件,执行如下

      • go install 也可以执行编译
      • D:\project> go build go_dev/day1/example1
      • go_build_example1
  • 2.6 Go包引用例子一

    • D:\project\src\go_dev\day1\package_example\calc

add.go ``` package calc

func Add(a int, b int) int { return a + b }


> sub.go

package calc

func Sub(a int, b int) int { return a - b }

> D:\project\src\go_dev\day1\package_example\main\main.go
  ```go
  package main

  import (
      "fmt"
      // 引用自定义的包
      "go_dev/day1/package_example/calc"
  )

  func main() {
      sum := calc.Add(200, 300)
      sub := calc.Sub(200, 400)
      fmt.Println("sum =", sum)
      fmt.Println("sum =", sub)
  }
  • 编译 -o 指定生成位置 编译后的名字win下必须带.exe结尾 否则无法执行

    • D:\project\bin> go build -o bin/calcTtest.exe go_dev/day1/package_example/main

    • 2.7 Go包引用例子二(channel)

    • D:\project\src\go_dev\day1\goroute_example\

D:\project\src\go_dev\day1\goroute_example\goroute\add.go

  package goroute

  func Add(a int, b int, c chan int) {

      sum := a + b
      // 将结果放入管道
      c <- sum
  }

D:\project\src\go_dev\day1\goroute_example\main\main.go

  package main

  import (
      "fmt"
      "go_dev/day1/goroute_example/goroute"
  )

  func main() {
      // 定义一个管道单位数值为1
      var pipe chan int
      pipe = make(chan int, 1)
      go goroute.Add(100, 300, pipe)

      sum :=< -pipe
      fmt.Println("sum =", sum)
  }
  • 编译 go build -o bin/gorouteText.exe go_dev/day1/goroute_example/main
    • 执行
      • D:\project\bin> .\gorouteText.exe
      • sum = 400
  • 使用fmt分别打印字符串、二进制、十进制、十六进制、浮点数。【homework】

D:\project\src\go_dev\day1\homework\printhw.go

  package main

  import (
      "fmt"
  )

  /*
    Printf: 只可以打印出格式化的字符串和变量。
    Println: 只可以打印出格式化的字符串、可以输出字符串类型的变量、不可以输出整形变量和整形。
     格式化输出信息一般选择Printf
  */

  func main() {
      str := 82
      fmt.Println("This is a string ", str)
      fmt.Printf("%b\n", str)
      fmt.Printf("%d\n", str)
      fmt.Printf("%x\n", str)
      fmt.Printf("%f\n", str)
      fmt.Println("homework reference: https://golang.org/pkg/fmt/")
  }
  D:\project> go build -o bin/printhw.exe go_dev/day1/homework/
  D:\project> .\bin\printhw.exe
  This is a string  82
  1010010
  82
  52
  %!f(int=82)
  homework reference: https://golang.org/pkg/fmt/
Copyright © zhangluya.com 2019            UPDATE 2020-03-26 15:42:33

results matching ""

    No results matching ""