为什么需要 go语言

  • 其他语言的弊端
    • 硬件发展速度远远超过软件
    • c语言等原生语言 缺乏好的依赖管理【依赖于头文件】
    • java 和 c++ 等语言过于笨重
    • 系统语言对垃圾回收和并行计算等基础功能缺乏支持
    • 对多核计算机缺乏支持
  • go是个 可以编译高效、支持高并发、垃圾回收的全新语言
    • 秒级 完成大型项目的单点编译
    • 依赖管理清晰
    • 不支持继承,程序员无需花费精力定义不同类型之间的关系
    • 支持垃圾回收,并发执行,多线程通讯
    • 对多核计算机支持友好

go语言不支持的特性

  • 不支持函数重载和操作符重载
  • 避免在 c/c++ 开发中的一些 bug 和 混乱,不支持隐式转换
  • 支持接口抽象,不支持继承
  • 不支持动态加载代码
  • 不支持动态链接库
  • 通过 recover 和 panic 代替异常机制
  • 不支持断言
  • 不支持静态变量

image-20211128010406544

环境目录

  1. GOPATH

    1. src: 存放源代码
    2. pkg 存放依赖包
    3. bin 存放可执行文件
  2. GOROOT

    1. go的安装目录
  3. 其他变量

    1. GOOS、GOARCH、GOPROXY
    2. 国内用户 建议设置 goproxy: export GOPROXY=https://goproxy.cn

    go的常用命令

    1
    2
    3
    4
    
    set GOOS=linux
    # 设置 golang 的 os 操作系统是 linux
    go build main.go 
    # 获得的文件 只能在 linux 执行
    

一些基本的命令

  • bug start a bug report

  • build compile packages and dependencies

  • clean remove object files and cached files

  • doc show documentation for package or symbol

  • env print GO environment information

  • fix update packages to use new APIS

  • fmt gofmt (reformat) package sources

  • generate generate go files by processing source

  • get add dependencies to current module and install them

  • install compile and install packages and dependencies

  • list list packages or modules

  • mod module maintenance

  • run compile and run Go program

  • test test packages

  • tool run specified go tool

  • version print Go version

  • vet report likely mistakes in packages

1
2
go fmt main.go
# go 自动帮你格式化,不需要你自己 格式化了

Go test

go语言自带 测试框架

1
2
3
4
5
import "testing"
func TestIncreates(t *testing.T) {
    t.Log("start testing")
    increase(1,2)
}
1
2
3
go test ./... -v 
# 运行测试
go test main_test.go  -v

go test 命令 扫描 所有 *_test.go 为结尾的文件,惯例是将测试代码与正式代码放在同一个目录下面 , 如 foo.go 测试代码 一般写在 foo_test.go

-v 是用于输出所有Log的信息

也可以指写具体的方法名,只要包含这些名称的测试方法就会运行,如果要测试多个方法,名称用"|“分开

参考博客

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package main

import (
	"testing"

	assert "github.com/stretchr/testify/assert"
)

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

func Test_increase(t *testing.T) {
	t.Log("hello world")
	var result = add(1, 2)
	assert.Equal(t, result, 3)

}

go vet

代码静态检查,发现可能的 bug 或者 可疑的构造

  • Print-format 错误,检查类型不匹配的print
1
2
var str = "hello world !"
fmt.Printf("%v\n", str)
  • boolean 错误,检查一直为 true,false 或者冗余的表达式
1
fmt.Println( i!=0 || i!=1)
  • Range 循环,比如以下代码 主协程 会先退出, go routine 无法执行
1
2
3
4
5
6
7
var words = []string{"foo","bar","baz"}

for _,word := range words {
    go func() {
        fmt.Println(word) 
    }()
}
  • unreachable 的代码,例如 return 之后的代码
  • 其他错误,比如 变量自复制,error 滞后等
1
2
3
4
5
var res,err = http.Get("https://www.baidu.com")
defer res.Body.Close()
if err != nil {
    log.Fatal(err)
}

参考项目

https://github.com/cncamp/golang

设计系统的时候, 优先用组合 而不是继承,因此 golang 支持组合 不支持继承 就是这样的。

go 和 java 的编译区别

java 可以将类库 导出一个个 的 jar 包,然后用 classLoader 来加载,但是 go 必须将 代码 包拉到本地,然后 再统一 编译到一个 二进制文件里面,这就是 区别

Golang playground

官方 playground https://play.golang.org/ 可直接编写和运行 Go 语言程序 国内可直接访问的 playground