基础
语言象限图
go 环境配置
变量 | 值 | 说明 |
---|---|---|
GOPATH | 定义go的项目目录,可以定义多个 | |
GOROOT | /usr/local/go | go的安装路径 |
Go项目目录结构
重点关注src目录下的目录结构,因为目录下为我们编写项目的项目源码目录
开源项目 使用gin快速搭建WEB站点以及提供RestFull接口的目录结构如下
src/github.com/ffhelicopter/tmm
/api
/handler
/model
/task
/website
main.go // 文件中定义了 package main
当我们运行go install main.go
会在GOPATH/bin
目录中生成可执行文件。
常用命令
- go get 动态获取远程代码包(内部实际上分成了两步操作)
- 从远程下载需要用到的包
- 执行 go install
- go install 内部实际上分成了两步操作
- 生成可执行文件或者
.a
的包 - 把编译好的结果移动到 bin/pkg 目录下
- 生成可执行文件或者
- go build
- 如果是普通包,不会产生任何文件
- 如果需要在pkg下生成相应文件,就得执行 go install
- 如果某个项目目录下有多个文件,你只想编译某个文件,使用 go build filename.go
- 也可以指定编译输出的文件名
go build -o astaxie.exe
- 会忽略目录下以
_/.
开头的go文件 - 如果源码针对不同的操作系统需要不同的处理,你可以根据不同的操作后缀来命名文件。
- array_linux.go
- array_windows.go
- array_freebsd.go
- go clean 用来移除当前源码包和关联源码包里编译生成的文件
- go fmt 格式化代码文件
- go test 自动读取源码目录下命名为
*_test.go
的文件,生成并运行测试用的可执行文件。 - go tool
- go tool fix 用来修复以前老版本的代码到新版本
- go tool vet directory | fiels 用来分析当前目录的代码是否都是正确的代码。
- go generate 用于在编译前自动化生成某类代码
- go doc
- go version 查看go当前的版本
- go env 查看当前go的环境变量
- go list 列出当前全部安装的 package
- go run 编译并运行 go 程序
开发工具
- gocode
- gopkgs
- go-outline
- go-symbols
- guru
- gorename
- dlv
- godef
- goreturns
- golin
- 有且仅有一个入口
main
- 左大括号
{
必须与函数名同行 Println()
会自动换行- 调用函数大部分都需要 import 包
golang
以包package
为管理单位- 每个文件必须先声明包
- 程序必须有一个
main
包 - 导入包必须使用
- 变量声明后,必须使用
// demo01
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello go!")
}
注释
Go也支持单行注释和块注释
// Cap returns the capacity of the buffer's underlying byte slice,
// that is, the total space allocated for the buffer's date
/*
Cap returns the capacity of the buffer's underlying byte slice,
that is, the total space allocated for the buffer's date
*/
// 函数之前的注释称为文档注释,应该以函数名同名开头
// enterOrbit causes Superman to fly into low Earth orbit, a position
// that presents several possibilitles for planet salvation.
func enterOrbit() error {
// do something
}
map类型
package main
// 声明与初始化
func main() {
var m map[string]int //map声明后,需要使用make分配内存空间
//m = make(map[string]int)
m["a"] = 1
//if v := m["b"]; v != nil { //b map取值时,返回v的默认零值
if v, ok := m["b"]; ok {
println(v)
}
}
// map 循环赋值
const N = 3
func main() {
m := make(map[int]*int)
for i := 0; i < N; i++ {
j := int(i)
m[i] = &j
}
for _, v := range m {
print(*v)
}
}
指针
package main
type S struct {
m string
}
// 修改 A和B的行,确保输出 foo
func f() *S {
return __ //A
}
func main() {
p := __ //B
print(p.m) //print "foo"
}
// 修改后
type S struct {
m string
}
func f() *S {
return new(S)//A
}
func main() {
p := S{"foo"} //B
print(p.m) //print "foo"
}
接收输入
func main() {
var a int
fmt.Printf("请输入变量a:")
// 接收单个输入
// fmt.Scanf("%d", &a)
fmt.Scan(&a)
fmt.Println("a =", a)
var aa int
var bb float64
var cc string
// 接收多个输入,按指定格式读取输入
fmt.Println("please enter s string: ")
fmt.Scanf("%d, %f, %s", &aa, &bb, &cc)
fmt.Println("output", aa, bb, cc)
/*
please enter s string:
3333, 3.1111, hhhhhhhhhhhhhhhhh
output 3333 3.1111 hhhhhhhhhhhhhhhhh
*/
// 接收多个输入, 按空格分割读取输入
fmt.Scanln(&aa, &bb, &cc)
fmt.Println("output", aa, bb, cc)
/*
please enter s string:
300 3.4 haha
output 300 3.4 haha
please enter s string:
300, 3.4 , haha
output 300
*/
reader := bufio.NewReader(os.Stdin)
data, _, _ := reader.ReadLine() // 返回字节切片
fmt.Println(data)
dataStr, _ := reader.ReadString('\n') // 指定结束字节符,接收输入;返回值为 string
fmt.Println(dataStr)
}
作用域
什么是作用域
声明语句的作用域是指源代码中可以有效使用这个名字的范围。
一个声明语句将程序的实体和一个名字关联:var name int =10
,函数func Add(a, b int) int
不要将作用域与生命周期混为一谈。
类型判断
作用:类型断言表达式断言类型的变量X.(T)
value, ok := variable.(type)
// variable 必须是接口类型
// type 是想要判断的类型
例如
package main
import "fmt"
var container = []string("zero", "one", "two")
func main() {
value, ok := interface{}(container).([]string)
fmt.Println(value, ok)
}
deffer
类似于 pyton中的 try...exception
的final
func Clear() {
fmt.Println("Clear resource.")
}
func TestDefer(t *testing.T) {
defer Clear()
fmt.Println("Start")
}
// output:
// Start
// Clear resource.
func TestDefer(t *testing.T) {
defer Clear()
fmt.Println("Start")
panic("err")
}
// output:
// Start
// Clear resource.
// FAIL:
// panicf: err [recovered]
// panic: err