Go语言第一天

内容介绍

  • Go语言简述

  • Go语言站点

  • Go基础环境搭建(linux&windows)

  • hello word程序

  • Go语言特性

  • Go命令介绍

Go语言简述

  • 特征:

    • 语法简单:语法标准比较严格,适合开发人员短时间高效的服务端开发。

    • 并发模型:Goroutine是Go最显著的特征,使用类协程的方式来处理并发,搭载channel实现CSP模型

    • 内存分配:Go选择tcmaclloc来实现高并发的内存管理和分配

    • 垃圾回收:防止出现OOM的坑

    • 静态链接:简化了部署和发布操作,极大程度上降低了代码发布的依赖关系

    • 标准库:功能完善的标准库,有利于降低学习成本

    • 工具链:无论是编译,格式化,错误检查,帮助文档和对应的测试支持都比较完善

  • 总结:

      go语言作为一个现代化的开发语言,利用其高并发的特性,有利于实现服务端开发;再结合自身的语法规范性上,可以更好的为API的开发提供更好的帮助;作为一种编译性开发语言。在web开发方面还存在着一定的高效性差距;然而在通过同步方式封装异步概念来更好的处理并发,所以更适合现在的服务端开发。

Go语言站点

官方站点:https://golang.org/dl/

官方站现在不能访问,提供如下的下载站点:https://golangtc.com/static/go/1.9.2/go1.9.2.linux-amd64.tar.gz

开发IDE链接:http://www.jetbrains.com/go/golang.com/d

Go语言环境搭建

Linux下配置Go

  • 下载对应的:go1.9.2.linux-amd64.tar.gz

  • 解压文件tar xf go1.9.2.linux-amd64.tar.gz –C /usr/local

  • 设置环境变量

 

root#vim /etc/profile
export GOROOT=$PATH:/path/to/go/
export PATH=$PATH:$GOROOT/bin/
export GOPATH=/home/user/project/go
root# source /etc/profile

window下安装Go

  • 下载好对应的安装包:go1.9.2.windows-amd64.msi

  • 双击安装

  • IDE下载:http://www.jetbrains.com/go/

  • 安装IDE

  • 测试环境变量,打开cmd命令行,输入go env即可显示环境变量

 

C:\Users\wanghui>go  env
set GOARCH=amd64
set GOBIN=
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=E:\project\       #项目环境变量,一个项目有且仅有这一个配置变量,不然会导致环境混乱;设置方式需要在windows上添加此项配置
set GORACE=
set GOROOT=D:\MyDevSoftInstallDir\Go
set GOTOOLDIR=D:\MyDevSoftInstallDir\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0
set CXX=g++
set CGO_ENABLED=1
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config

hello world程序

  • 创建项目路径并且配置GOPATH环境变量,我在电脑E盘下创建了一个文件夹,名称是project,作为项目的GOPATH

  • 打开IDE,选择好对应的项目路径并打开

创建如下的目录结构:

hello.go代码如下:

 

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

运行代码:go run hello.go

工作区介绍

  • GOPATH

    • 所有的项目都要放到$GOPATH/src

    • GOPATH的路径最好配置一个

    • 注意要有良好的目录结构

基本命令介绍

首先建立如下的目录结构:

 

├─program
│    └─src
|       └─code.oldboy.com
│            └─day1

所有的项目就从day1的同一级目录开始,咱们先写一个求和求差的小程序:

  • day1/calc/Calc.go

package calc
//求和
func Add(a int,b int) int {
    return a + b
}
//求差
func Sub(a int,b int) int {
    return a - b
}
//多返回值混合运算
func Calc(a int,b int) (int,int) {
    sum := a + b
    sub := a - b
    return sum,sub
}
  • da1/hello/hello2.go

 

package main
//导入模块
import (
    "code.oldboy.com/day1/calc"
    "fmt"
)
//main入口函数
func main() {
    //定义变量给单个retun的Add和Sub使用
    var sum int
    var sub int
    sum = calc.Add(100,200)
    sub = calc.Sub(300,10)
    //定义变量给多个返回值的Calc函数使用
    sum_1,sub_1 := calc.Calc(100,50)
    fmt.Println(sum,sub)
    //格式化打印结果
    fmt.Printf("muti return sum is %d,sub is %d ",sum_1,sub_1)
}

go run

在CMD终端执行

 

E:\>cd program
E:\program>cd src
E:\program\src>cd code.oldboy.com
E:\program\src\code.oldboy.com>cd day1
E:\program\src\code.oldboy.com\day1>cd hello
E:\program\src\code.oldboy.com\day1\hello>go run hello.go
hello word!!
E:\program\src\code.oldboy.com\day1\hello>go run hello2.go
300 290
muti return sum is 150,sub is 50

go run 运行的入口文件   这样就能够不需要编译直接执行,不需要考虑到依赖关系,可以理解成自动编译执行。

go build 

这个操作就是要进行编译程序,然后根据操作平台,指定生成一个可执行程序。同样也是解决了依赖,直接就执行就好。

 

E:\>cd program
E:\program>go build -o bin/Hello2.exe code.oldboy.com/day1/hello     #编译程序
E:\program>cd bin
E:\program\bin>Hello2.exe     #执行生成的文件
300 290
muti return sum is 150,sub is 50

go install

go install会依次查找所有GOPATH中的目录寻找hello包和它依赖的code.oldboy.com/day1/hello包。然后会将报名为main的包生成二进制文件放到GOBIN目录下。将非main包编译成.a文件放到项目对于的pkg目录下

 

E:\program>go install code.oldboy.com/day1/hello
E:\program>cd pkg
E:\program\pkg>dir
2017/11/29  16:17    <DIR>          .
2017/11/29  16:17    <DIR>          ..
2017/11/29  16:17    <DIR>          windows_amd64
E:\program\pkg>cd windows_amd64
E:\program\pkg\windows_amd64>dir
2017/11/29  16:17    <DIR>          .
2017/11/29  16:17    <DIR>          ..
2017/11/29  16:17    <DIR>          code.oldboy.com
E:\program\pkg\windows_amd64>tree
文件夹 PATH 列表
卷序列号为 704D-FB7A
E:.
└─code.oldboy.com
    └─day1
E:\program\pkg\windows_amd64>cd code.oldboy.com/
E:\program\pkg\windows_amd64\code.oldboy.com>cd day1
E:\program\pkg\windows_amd64\code.oldboy.com\day1>dir
E:\program\pkg\windows_amd64\code.oldboy.com\day1 的目录
2017/11/29  16:17    <DIR>          .
2017/11/29  16:17    <DIR>          ..
2017/11/29  16:17             1,694 calc.a

go test

go test是执行单元测试或者压力测试

下面就是一个测试样例,代码如下:

  • code.oldboy.com/day1/calc/test/calc_test.go

 

package test
//导入测试包
import(
    "testing"
    "code.oldboy.com/day1/calc"
)
//测试函数
func TestAdd(t *testing.T){
    var sum int
    sum = calc.Add(5,6)
    if sum != 11{
        t.Fatalf("add is not correct,sum:%v expected 11",sum)
    }
    t.Logf("add is ok!")
}
func TestSub(t *testing.T){
    var sub int
    sub = calc.Sub(5,6)
    if sub != -1 {
        t.Fatalf("sub is not right,sub:%v -1",sub)
    }
    t.Logf("sub is ok!!")
}

执行测试:

 

E:\program>cd src
E:\program\src>cd code.oldboy.com
E:\program\src\code.oldboy.com>cd day1
E:\program\src\code.oldboy.com\day1>cd calc
E:\program\src\code.oldboy.com\day1\calc>cd test
E:\program\src\code.oldboy.com\day1\calc\test>go test calc_test.go
ok      command-line-arguments  1.399s

go env

显示环境变量

cmd下执行

 

E:\program>go env
set GOARCH=amd64
set GOBIN=
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=E:\program
set GORACE=
set GOROOT=D:\Program Files (x86)\Go
set GOTOOLDIR=D:\Program Files (x86)\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0
set CXX=g++
set CGO_ENABLED=1
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config

go fmt

格式化代码,以便统一代码风格。

 

#单个文件格式化
E:\program>cd src
E:\program\src>cd code.oldboy.com
E:\program\src\code.oldboy.com>cd day1
E:\program\src\code.oldboy.com\day1>cd hello
E:\program\src\code.oldboy.com\day1\hello>go fmt hello2.go  #单个文件格式化
hello2.go
#所有项目全部格式化
E:\program>gofmt -w -l src
src\code.oldboy.com\day1\calc\calc.go
src\code.oldboy.com\day1\calc\test\calc_test.go
src\home_exe\calc\calc.go

go程序结构

  • go源码按照package进行组织,并且package要放到非注释行的第一行

    • package

  • 一个程序只能有一个main包和一个main函数

  • main函数是程序的执行入口

  • 注释:

 

//这是单行注释
--------分界线---------
/*这是
多行
注释*/

go语言特性

  • 垃圾回收

    • 内存自动回收,不需要人工干预

    • 开发人员专注业务实现,降低了心智负担

    • 只需要new分配内存,不需要释放

  • 天然并发

    • 从语言层面支持并发,非常简单

    • goroutine轻量级线程,是的创建上万个goroute成为可能

    • 基于CSP模型实现

    • 下面就是一个打印技术和偶数的例子src/oldboy.com/day1/threads/main.go

 

package main
import (
    "fmt"
    "time"
)
func PrintOdd(n int){
    for i := 0; i < n; i++{
        if i % 2 == 1 {
            fmt.Printf("Odd is %d", i)
        }
    }
}
func PrintEven(n int){
    for i := 0; i < n ;i++{
        if i % 2 == 0 {
            fmt.Printf("Even is %d",i)
        }
    }
}

func main() {
    go PrintOdd(100)
    go PrintEven(100)
    time.Sleep(10*time.Second)
}

执行结果如下:

 

E:\program>go build -o bin/threads.exe code.oldboy.com/day1/threads
E:\program>cd bin
E:\program\bin>threads.exe
Odd is 1Odd is 3Odd is 5Odd is 7Odd is 9Odd is 11Odd is 13Odd is 15Odd is 17Odd
is 19Odd is 21Odd is 23Odd is 25Odd is 27Odd is 29Odd is 31Odd is 33Odd is 35Odd
 is 37Odd is 39Odd is 41Odd is 43Odd is 45Odd is 47Odd is 49Odd is 51Odd is 53Od
d is 55Odd is 57Odd is 59Odd is 61Odd is 63Odd is 65Odd is 67Odd is 69Odd is 71O
dd is 73Odd is 75Odd is 77Odd is 79Odd is 81Odd is 83Odd is 85Odd is 87Odd is 89
Odd is 91Odd is 93Odd is 95Odd is 97Odd is 99Even is 0Even is 2Even is 4Even is
6Even is 8Even is 10Even is 12Even is 14Even is 16Even is 18Even is 20Even is 22
Even is 24Even is 26Even is 28Even is 30Even is 32Even is 34Even is 36Even is 38
Even is 40Even is 42Even is 44Even is 46Even is 48Even is 50Even is 52Even is 54
Even is 56Even is 58Even is 60Even is 62Even is 64Even is 66Even is 68Even is 70
Even is 72Even is 74Even is 76Even is 78Even is 80Even is 82Even is 84Even is 86
Even is 88Even is 90Even is 92Even is 94Even is 96Even is 98
  • channel

    • 管道,类似unix中的pipe

    • 多个goroute之间通过channel进行通信

    • 支持任何类型的数据传输

    • 下面是个小例子:src/oldboy.com/day1/pipe/main.go

 

package main
import "fmt"
func main(){
    //创建channel
    pipe := make(chan string,3)
    //插入值
    pipe <- "a"
    pipe <- "b"
    pipe <- "c"
    //取出值
    var a1 string
    a1 =<- pipe
    fmt.Printf("%s",a1)
}

执行出来的结果如下:

  • 多个返回值,可以参考calc/Calc.go

 

//多返回值混合运算
func Calc(a int,b int) (int,int) {
    sum := a + b
    sub := a - b
    return sum,sub
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章