1. Go入门

1.1.1. 1.1 Linux搭建Go环境

1.ssh远程登录Linux服务器,可选用iTerm、xshell

ssh root@ip

2.建议配置好阿里云yum源、epel源

安装git

yum install git

3.下载go源码包

//下载地址 go官网 https://golang.org/dl/
cd /opt/
wget https://dl.google.com/go/go1.11.4.linux-amd64.tar.gz

4.解压缩go源码包,确认当前linux系统版本是32位还是64位,再选择go源码包

//查看linux多少位
[root@pyyuc /opt 21:59:02]#uname -m
x86_64

//决定下载64位
tar -zxvf go1.11.4.linux-amd64.tar.gz

//解压缩后go源码路径确保为
/opt/go/

5.配置go的工作空间(配置GOPATH),以及go的环境变量

go的代码必须在GOPATH中,也就是一个工作目录,目录包含三个子目录

$GOPATH
    src        存放go源代码的目录,存放golang项目的目录,所有项目都放到gopath的src目录下
    bin        在go install后生成的可执行文件的目录
    pkg        编译后生成的,源码文件,如.a

创建/opt/gocode/{src,bin,pkg},用于设置GOPATH为/opt/godocer

mkdir -p /opt/gocode/{src,bin,pkg}

/opt/gocode/
├── bin
├── pkg
└── src

6.设置GOPATH环境变量

修改/etc/profile系统环境变量文件,写入GOPATH信息以及go sdk路径

export GOROOT=/opt/go           #Golang源代码目录,安装目录
export GOPATH=/opt/gocode        #Golang项目代码目录
export PATH=$GOROOT/bin:$PATH    #Linux环境变量
export GOBIN=$GOPATH/bin        #go install后生成的可执行命令存放路径

读取/etc/profile,立即生效

source /etc/profile     #读取环境变量

查看go环境是否生效

//查看go环境变量路径
which go
//查看go语言环境信息
go env
//查看go版本,查看是否安装成功
[root@pyyuc ~ 22:59:05]#go version
go version go1.11.4 linux/amd64

1.1.2. Linux下第一个go程序

1.进入GOPATH工作目录

cd /opt/gocode/src  #进入src代码目录
mkdir hellogo        #新建一个go代码"包",hellogo
cd hellogo            #切换go包的目录,hellogo目录
touch main.go        #创建go程序文件

2.编辑main.go写入如下代码

[root@pyyuc /opt/gocode/src/hellogo 23:18:18]#cat main.go
package main

import "fmt"

func main() {
    fmt.Println("你好,欢迎来到超哥的golang世界")
}

3.运行go代码文件

//go run直接编译+运行go代码文件
[root@pyyuc /opt/gocode/src/hellogo 23:18:20]#go run main.go
你好,欢迎来到超哥的golang世界

//go fmt格式化go代码文件,统一代码风格
[root@pyyuc /opt/gocode/src/hellogo 23:20:13]#go fmt main.go

//go build 编译一个二进制可执行程序,用于编译指定的源码文件或代码包以及它们的依赖包。
[root@pyyuc /opt/gocode/src/hellogo 23:20:16]#go build main.go
[root@pyyuc /opt/gocode/src/hellogo 23:22:43]#ls
main  main.go

//执行二进制命令,这个命令可以拖动到其他linux机器,直接使用
[root@pyyuc /opt/gocode/src/hellogo 23:22:44]#./main
你好,欢迎来到超哥的golang世界

//go install编译一个二进制可执行程序,放在GOBIN目录下,也就是在$GOPATH/bin目录下
[root@pyyuc /opt/gocode/src/hellogo 23:35:54]#go install main.go
[root@pyyuc /opt/gocode/src/hellogo 23:36:04]#ls ../../bin/

1.1.3. 1.3 Windows搭建Go环境

1.1.4. Golang SDK

1) SDK 的全称(Software Development Kit 软件开发工具包) 2) SDK是提供给开发人员使用的,其中包含了对应开发语言的工具包

1.1.5. 下载SDK工具包

windows用户安装golang可以选择两种方式:

go1.11.4.windows-386.zip    //zip压缩包需要手动设置go环境变量
go1.11.4.windows-386.msi    //msi包自动一键安装go环境变量

1.下载windows下的go开发工具

https://golang.org/dl/  //官方下载地址
https://dl.google.com/go/go1.11.4.windows-amd64.msi
https://dl.google.com/go/go1.11.4.windows-386.zip

2.安装golang开发环境

一键安装完毕后,查看GOROOT的安装目录

3.设置golang环境变量

添加windows的PATH变量,用于便捷的输入go命令

windows在cmd中输入go指令,系统会去PATH定义的环境变量中,查找是否有对应的程序目录,以便于在任何目录下都可以随意使用go指令
如go env
$GOROOT  指向golang安装之后的根目录,如果你选择.msi安装的话,windows平台下默认为c:/go,而且在安装过程中由安装程序自动写入系统环境变量。
$GOARCH  目标平台(编译后的目标平台)的处理器架构(386、amd64、arm)
$GOOS      目标平台(编译后的目标平台)的操作系统(darwin、freebsd、linux、windows)
$GOBIN    指向安装之后根目录下的bin目录,即$GOROOT/bin,windows平台下默认为c:/go/bin,会在安装过程中由安装程序自动添加到PATH变量中

1.1.6. 2.1Go语言特性

1.1.7. 编程语言类型

静态语言,动态语言

静态语言:强类型语言

​    定义变量,必须指明数据类型,存储对应类型的数据。

​    例如java,go,c

动态语言:弱类型语言

​    定义变量,赋值过程决定变量类型

​    如js,python

1.1.8. Go程序执行流程

对源代码编译成二进制后运行

.go代码源文件    >    go build    >    可执行文件(.exe或linux二进制命令)    >    运行结果

对源代码直接运行

.go代码文件        >    go run         >    结果
源代码                编译且运行(不会生成二进制命令)

二者区别

1.使用go build编译生成的二进制的程序,可以直接放在同类系统上直接运行,无须go开发环境
2.go run运行代码,在另一台及其上,仍然需要go开发环境,否则无法运行
3.go build,编译器会对程序依赖的库文件打包在可执行文件中,因此可执行文件体积稍大
4.windows环境go build生成的二进制命令文件,名字以.exe结尾
5.Linux环境go build 生成一个同名的二进制命令

1.1.9. Go语言注意事项

1.Go代码都是以.go后缀
2.Go代码的执行入口函数是main()函数
3.Go语言严格区分大小写
4.Go代码语句结尾不需要分号,编译器自动识别
5.Go代码按行进行编译,一行尽量只写一条语句
6.Go语言的简洁性使得代码中不得含有未使用的变量,以及未使用的包
7.Go语言通过大括号控制代码
8.使用go fmt 统一代码风格

1.1.10. Go语言的转义字符(escape char)

\t    一个制表符,代表一次tab
\n    换行符
\\    转义代表 \
\"    转义代表 "
\r    一个回车,从当前行的最前面开始输出,会覆盖以前的内容,常配合\r\n换行使用

1.1.11. Go语言注释

代码注释是用于解释程序的文字,注释可以提高代码可读性

//        行注释
//本行已被注释

/* */块注释

/* 本段落被注释
本段落被注释*/

对于行注释和快注释,被注释的内容不会被Go编译器执行
注意: 块注释中不得嵌套块注释

1.1.12. Golang官方标准API文档

https://golang.org/pkg

1) API (Application Programming Interface,应用程序编程接口)是 Golang 提供的基本编程接口。
2) Go 语言提供了大量的标准库,因此 google 公司 也为这些标准库提供了相应的 API 文档,用于告 诉开发者如何使用这些标准库,以及标准库包含的方法。
3) Golang 中文网 在线标准库文档: https://studygolang.com/pkgdoc

1.1.13. Go语言命名

编码:源码文件必须是 UTF-8 格式,否则会导致编译器出错。
命名:采用 camelCasing 风格(驼峰命名法),不建议使用下划线。

1.1.14. 编码格式

ASCII 美国标准信息交换码
中国:GBK,中文常用字符
台湾:大五码

unicode编码,万国码,统一全世界的编码,把所有编码进行排号,拥有自己的编码,不兼容其它码表
UTF-8 变长字符集

1.1.15. Go变量类型

内置类型 值类型:

bool                                                        布尔类型
int(32 or 64), int8, int16, int32, int64                    整数类型
uint(32 or 64), uint8(byte), uint16, uint32, uint64            无符号整型
float32, float64                                            浮点型
string                                                        string
array                                                       固定长度的数组
struct                                                        结构体

引用类型:(指针类型)

slice       切片
map         映射
chan        管道
interface    接口

1.1.16. 2.3 Go内置函数

内置函数 Go 语言拥有一些不需要进行导入操作就可以使用的内置函数。它们有时可以针对不同的类型进行操作,例如:len、cap 和 append,或必须用于系统级的操作,例如:panic。因此,它们需要直接获得编译器的支持。

append          -- 用来追加元素到数组、slice中,返回修改后的数组、slice
close           -- 主要用来关闭channel
delete            -- 从map中删除key对应的value
panic            -- 停止常规的goroutine  (panic和recover:用来做错误处理)
recover         -- 允许程序定义goroutine的panic动作
imag            -- 返回complex的实部   (complex、real imag:用于创建和操作复数)
real            -- 返回complex的虚部
make            -- 用来分配内存,返回Type本身(只能应用于slice, map, channel)
new                -- 用来分配内存,主要用来分配值类型,比如int、struct。返回指向Type的指针
cap                -- capacity是容量的意思,用于返回某个类型的最大容量(只能用于切片和 map)
copy            -- 用于复制和连接slice,返回复制的数目
len                -- 来求长度,比如string、array、slice、map、channel ,返回长度
print、println     -- 底层打印函数,在部署环境中建议使用 fmt 包

init函数

go语言中init函数用于包(package)的初始化,该函数是go语言的一个重要特性。

有下面的特征:

1 init函数是用于程序执行前做包的初始化的函数,比如初始化包里的变量等

2 每个包可以拥有多个init函数

3 包的每个源文件也可以拥有多个init函数

4 同一个包中多个init函数的执行顺序go语言没有明确的定义(说明)

5 不同包的init函数按照包导入的依赖关系决定该初始化函数的执行顺序

6 init函数不能被其他函数调用,而是在main函数执行之前,自动被调用

main函数

Go语言程序的默认入口函数(主函数):func main()
函数体用{}一对括号包裹。

func main(){
    //函数体
}

init函数和main函数的异同

相同点:
    两个函数在定义时不能有任何的参数和返回值,且Go程序自动调用。
不同点:
    init可以应用于任意包中,且可以重复定义多个。
    main函数只能用于main包中,且只能定义一个。

两个函数的执行顺序: 对同一个go文件的init()调用顺序是从上到下的。 对同一个package中不同文件是按文件名字符串比较“从小到大”顺序调用各文件中的init()函数。 对于不同的package,如果不相互依赖的话,按照main包中"先import的后调用"的顺序调用其包中的init(),如果package存在依赖,则先调用最早被依赖的package中的init(),最后调用main函数。

1.1.17. 2.4 Go与包

1)开发中,往往要在不同的文件中调用其他文件的函数

2)Go代码最小粒度单位是"包"

3)Go的每一个文件都属于一个包,通过package管理

4)Go以包的形式管理文件和项目目录结构

5)包的命名不要和保留名称重复

6)编译可执行文件,必须包含package main,入口函数为main()

1.1.18. Go包的作用

1)区分同名的函数、变量等标识符

2)管理项目程序文件

3)控制函数、变量访问作用域

4)Go包中的变量,以首字母大小写决定是否可以被导出(public),如Foo可以被导出,foo则不行(internal)

5)因此,在导入一个外部包后,能够,且只能够访问该包中导出的对象。

假设在包 pack1 中我们有一个变量或函数叫做 Thing(以 T 开头,是大写开头的,所以它能够被导出)

那么在当前包中导入 pack1 包,Thing 就可以像面向对象语言那样使用点标记来调用:

pack1.Thing //(pack1 在这里是不可以省略的)

6)不得导入未使用的包,编译器不通过

1.1.19. Go包目录结构

gostudy
    |
    +--- bin                 // go install 安装目录。
    |    |
    |     +--- hello            //可执行命令hello
    |
    +--- pkg             // go build 生成静态库 (.a) 存放目录。
    |      |
    |       +--- darwin_amd64 
    |                |
    |                 +--- lib.a 
    |                |
    |                 +--- lib 
    |                       |
    |                        +--- sublib.a
    |    
    +--- src             // 项目源码目录。
    |      |
    |      +---golearn
    |
    +--- learn
    |       |
    |        +--- main.go
    |

可在 GOPATH 环境变量列表中添加多个工作空间,但不能和 GOROOT 相同。

通常 go get使用第一个工作空间保存下载的第三方库。

1.1.20. Go包的导入

导入包 :使用包成员前,必须先用 import 关键字导入,但不能形成导入循环。

import "相对目录/包主文件名"

相对目录是指从<workspace>/pkg/<os_arch>开始的子目录,以标准库为例:

import "fmt"      ->  /usr/local/go/src/fmt

在导入时,可指定包成员访问方式。比如对包重命名,以避免同名冲突。

import用法

import "fmt"        最常用导入系统包
import "./test"        导入当前目录的包(相对路径)
import "gostudy/model     加载$gopath/src/gostudy/model模块(绝对路径)
import f "fmt"        导入fmt,且给与别名f,可以通过f. 方式调用函数
import . "fmt"         将fmt启用别名".",这样就可以直接使用其内容,而不用再添加fmt.Println()
import  _ "fmt"     表示不使用该包,而是只是使用该包的init函数,而不能够使用该包的其他函数。

1.1.21. Go包的语法使用

声明包
package 包名

引入包
import "包的路径"

1.2. Go格式化fmt包

golang 的fmt 包实现了格式化I/O函数,类似于C的 printf 和 scanf。

普通占位符

占位符     说明                           举例                   输出
%v      相应值的默认格式。            Printf("%v", people)   {zhangsan},
%+v     打印结构体时,会添加字段名     Printf("%+v", people)  {Name:zhangsan}
%#v     相应值的Go语法表示            Printf("#v", people)   main.Human{Name:"zhangsan"}
%T      相应值的类型的Go语法表示       Printf("%T", people)   main.Human
%%      字面上的百分号,并非值的占位符  Printf("%%")

布尔占位符

占位符       说明                举例                     输出
%t          true 或 false。     Printf("%t", true)       true

整数占位符

占位符     说明                                  举例                       输出
%b      二进制表示                             Printf("%b", 5)             101
%c      相应Unicode码点所表示的字符              Printf("%c", 0x4E2D)        中
%d      十进制表示                             Printf("%d", 0x12)          18
%o      八进制表示                             Printf("%d", 10)            12
%q      单引号围绕的字符字面值,由Go语法安全地转义 Printf("%q", 0x4E2D)        '中'
%x      十六进制表示,字母形式为小写 a-f         Printf("%x", 13)             d
%X      十六进制表示,字母形式为大写 A-F         Printf("%x", 13)             D
%U      Unicode格式:U+1234,等同于 "U+%04X"   Printf("%U", 0x4E2D)         U+4E2D

浮点数和复数的组成部分(实部和虚部)

占位符     说明                              举例            输出
%b      无小数部分的,指数为二的幂的科学计数法,
        与 strconv.FormatFloat 的 'b' 转换格式一致。例如 -123456p-78
%e      科学计数法,例如 -1234.456e+78        Printf("%e", 10.2)     1.020000e+01
%E      科学计数法,例如 -1234.456E+78        Printf("%e", 10.2)     1.020000E+01
%f      有小数点而无指数,例如 123.456        Printf("%f", 10.2)     10.200000
%g      根据情况选择 %e 或 %f 以产生更紧凑的(无末尾的0)输出 Printf("%g", 10.20)   10.2
%G      根据情况选择 %E 或 %f 以产生更紧凑的(无末尾的0)输出 Printf("%G", 10.20+2i) (10.2+2i)

字符串与字节切片

占位符     说明                              举例                           输出
%s      输出字符串表示(string类型或[]byte)   Printf("%s", []byte("Go语言"))  Go语言
%q      双引号围绕的字符串,由Go语法安全地转义  Printf("%q", "Go语言")         "Go语言"
%x      十六进制,小写字母,每字节两个字符      Printf("%x", "golang")         676f6c616e67
%X      十六进制,大写字母,每字节两个字符      Printf("%X", "golang")         676F6C616E67

指针

占位符         说明                      举例                             输出
%p      十六进制表示,前缀 0x          Printf("%p", &people)             0x4f57f0

其他标记

占位符      说明                             举例          输出
+      总打印数值的正负号;对于%q(%+q)保证只输出ASCII编码的字符。 
                                           Printf("%+q", "中文")  "\u4e2d\u6587"
-      在右侧而非左侧填充空格(左对齐该区域)
#      备用格式:为八进制添加前导 0(%#o)      Printf("%#U", '中')      U+4E2D
       为十六进制添加前导 0x(%#x)或 0X(%#X),为 %p(%#p)去掉前导 0x;
       如果可能的话,%q(%#q)会打印原始 (即反引号围绕的)字符串;
       如果是可打印字符,%U(%#U)会写出该字符的
       Unicode 编码形式(如字符 x 会被打印成 U+0078 'x')。
' '    (空格)为数值中省略的正负号留出空白(% d);
       以十六进制(% x, % X)打印字符串或切片时,在字节之间用空格隔开
0      填充前导的0而非空格;对于数字,这会将填充移到正负号之后

1.3. 实例

package main

import "fmt"

var area float32

func main() {
    area = 12345.678
    fmt.Printf("王思聪家的厨房面积%f平米\n", area)
    fmt.Printf("王思聪家的厨房面积%0.3f平米\n", area)
}

1.3.1. fmt包的函数

package main

import "fmt"

func main() {
    fmt.Println("a","b","c")
    fmt.Printf("名字%s 年纪%d\n","孙悟空",999)

    //获取字符串,返回字符串
    str:=fmt.Sprint("hello world",100,200)
    fmt.Println(str)

    //获取格式化字符串
    str2:=fmt.Sprintf("年纪:%d,姓名:%s\n",22,"行者孙")
    fmt.Println(str2)
}

1.4. go与stdin,读取键盘输入

fmt包提供了输入函数

  • Scan
  • Scanf
  • Scanln

1.4.1. Scan

func Scan(a ...interface{}) (n int, err error)

Scan从标准输入读取数据,以空格作为分隔(换行符也视作空格),依次将输入赋给参数。

他会返回读取参数的个数,和读取过程中遇到的错误。

package main

import "fmt"

func main() {
    var i int
    var num float32
    var s string
    //可以传入任意类型
    //scan以空格和换行分割
    res, err := fmt.Scan(&i, &num, &s)
    if err != nil {
        fmt.Println("err is :", err)
    }
    fmt.Println("参数个数", res)

    //用户输入会通过空格分割 保存在三个变量中
    fmt.Println(i, num, s)
}
// Code:
func main() {
  var s string
  fmt.Scan(&s)
}

// Input:
This is a string.

上述代码接受上述输入之后,s里面存储的是This,而is a string会继续保留在stdin中。

1.5. Scanf

func Scanf(format string, a ...interface{}) (n int, err error)

ScanfScan类似,只是可以自己定义输入格式。

package main

import "fmt"

func main() {
    var i int
    var d float32
    var s string

    num, err := fmt.Scanf("%d %f %s", &i, &d, &s)
    if err != nil {
        fmt.Println("err is :", err)
    }

    fmt.Println("参数个数:", num)
    /*
        用户输入的i存储 数字
        d存储浮点数
        s存储字符串
    */
    fmt.Println("用户输入信息:", i, d, s)
}

1.5.1. Scanln

func Scanln(a ...interface{}) (n int, err error)

ScanlnScan几乎一样,只不过Scanln换行符作为一次输入的结束

1.6. bufio包

使用bufio包可以更好的读取IO,以及文件读取

1.6.1. 随机数math/rand包

根据种子数,定义随机数

1.设置种子数

2.获取随机数

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    //随机数,根据底层算法公式,算出的结果,根据种子数seed计算
    //默认种子数是1
    //修改种子数,种子数固定,随机数也固定,因此可以根据纳秒时间戳来定义
    rand.Seed(time.Now().UnixNano()) //接收一个int64的数值,数值随意
    num1 := rand.Intn(10)            //获取[0,n) 的一个随机数
    fmt.Println(num1)
    num2 := rand.Intn(10) //获取[0,n) 的一个随机数
    fmt.Println(num2)
    num3 := rand.Intn(10) //获取[0,n) 的一个随机数
    fmt.Println(num3)
}

2. Hello golang

编写第一个hello golang

创建空文件hello.go,尝试执行

touch hello.go
go run hello.go

产生如下报错

can't load package: package main: 
gobook/main.go:1:1: expected 'package', found 'EOF'

解答:

在go语言中,所有go源码文件必须声明隶属于某一个包,至少一个package main,main为自己创建的包名。

2.1. 正确的hello golang

Go代码文件,程序中必须指定启动函数main(),如同小汽车的点火开关。

Hello.go

package main    //声明为main包,即可以编译成二进制程序

import "fmt"    //导入fmt格式化包

func main(){fmt.Println("hello golang")}    //main主函数入口

运行

go run hello.go

结果

hello golang

但是如上的代码,并不美观,go提供了格式化代码命令

go fmt hello.go

格式化后,代码风格如下

package main

import "fmt"

func main() {
    fmt.Println("hello golang")    //调用fmt包下的Println函数
}

3. 2.6 Golang命令

在命令行执行go命令查看相关的Go语言命令:

Go is a tool for managing Go source code.

Usage:

    go command [arguments]

The commands are:

    build       compile packages and dependencies
    clean       remove object files and cached files
    doc         show documentation for package or symbol
    env         print Go environment information
    bug         start a bug report
    fix         update packages to use new APIs
    fmt         gofmt (reformat) package sources
    generate    generate Go files by processing source
    get         download and install packages and dependencies
    install     compile and install packages and dependencies
    list        list packages
    run         compile and run Go program
    test        test packages
    tool        run specified go tool
    version     print Go version
    vet         report likely mistakes in packages

Use "go help [command]" for more information about a command.

Additional help topics:

    c           calling between Go and C
    buildmode   build modes
    cache       build and test caching
    filetype    file types
    gopath      GOPATH environment variable
    environment environment variables
    importpath  import path syntax
    packages    package lists
    testflag    testing flags
    testfunc    testing functions

Use "go help [topic]" for more information about that topic.

实用命令

godoc -http=:8888    本地启动一个go官网
也可以
go doc fmt.printf 直接在本地查看函数表准用法

go env用于打印Go语言的环境信息。

go run命令可以编译并运行命令源码文件。

go get可以根据要求和实际情况从互联网上下载或更新指定的代码包及其依赖包,并对它们进行编译和安装。

go build命令用于编译我们指定的源码文件或代码包以及它们的依赖包。

go install用于编译并安装指定的代码包及它们的依赖包。

go clean命令会删除掉执行其它命令时产生的一些文件和目录。

go doc命令可以打印附于Go语言程序实体上的文档。我们可以通过把程序实体的标识符作为该命令的参数来达到查看其文档的目的。

go test命令用于对Go语言编写的程序进行测试。

go list命令的作用是列出指定的代码包的信息。

go fix会把指定代码包的所有Go语言源码文件中的旧版本代码修正为新版本的代码。

go vet是一个用于检查Go语言源码中静态错误的简单工具。

go tool pprof命令来交互式的访问概要文件的内容。

4. 2.7 Go交叉编译

Golang 支持交叉编译,在一个平台上生成另一个平台的可执行程序,最近使用了一下,非常好用,这里备忘一下。

Mac 下编译 Linux 和 Windows 64位可执行程序

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go

Linux 下编译 Mac 和 Windows 64位可执行程序

CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build main.go
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go

Windows 下编译 Mac 和 Linux 64位可执行程序

SET CGO_ENABLED=0
SET GOOS=darwin
SET GOARCH=amd64
go build main.go

SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64
go build main.go

GOOS:目标平台的操作系统(darwin、freebsd、linux、windows) GOARCH:目标平台的体系架构(386、amd64、arm) 交叉编译不支持 CGO

results matching ""

    No results matching ""