公司建议我们改用Go开发microService已经有一段时间了,因为项目时间紧,没有把已有的services重写,但是如果再写新service,要尽量用Go了。以前曾经过了一遍官方网站的基础教程,几个月后就完全不记得了,所以总结一下知识点,以便有需要时能迅速复习。不必记住语法细节,知道语言的特点,能做什么,更重要,具体语法Stack Overflow一搜就有了。
Table of Contents
Call code in an external package
Call your code from another module
Return greetings for multiple people
Compile and install the application
https://golang.org/doc/
- concurrency
- garbage collection
- run-time reflection
- fast
- statically typed
- compiled language that feels like a dynamically typed, interpreted language
Tutorial: Getting started
https://golang.org/doc/tutorial/getting-started
写代码并使用go run
用package组织代码
有一些standard library packages,比如fmt
A main function executes by default when you run code in the file
$ go run hello.go
Hello, World!
👆 看起来确实有点像解释执行
查看help:
go help
Call code in an external package
去这里找packages,https://pkg.go.dev/
不用下载什么的,直接import就行,要创建go.mod。When your code imports packages from another module, a go.mod file lists the specific modules and versions providing those packages.
$ go mod init hello
go: creating new go.mod: module hello
👆 这里的hello是module name,不是package name,注意区分
$ go run hello.go
go: finding module for package rsc.io/quote
go: downloading rsc.io/quote v1.5.2
go: found rsc.io/quote in rsc.io/quote v1.5.2
go: downloading rsc.io/sampler v1.3.0
go: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
Don't communicate by sharing memory, share memory by communicating.
这里是go run时download package的,Matt:那production肯定不是这么干,肯定有命令来做build,然后有命令来只是run
使用Module
A tutorial of short topics introducing functions, error handling, arrays, maps, unit testing, and compiling.
Create a Go module
https://golang.org/doc/tutorial/create-module
Your package's module specifies the context Go needs to run the code, including the Go version the code is written for and the set of other modules it requires.
$ go mod init example.com/greetings
go: creating new go.mod: module example.com/greetings
in production code, this would be the URL from which your module can be downloaded. Matt:我理解是说我们要在这里host我们的module。问题,可否不以源码形式而是以binary形式发布?
现在这个go.mod文件只是包含名字和go lang版本,But as you add dependencies -- meaning packages from other modules -- the go.mod file will list the specific module versions to use.
:=是个syntax sugar,并且它可以infer type
message := fmt.Sprintf("Hi, %v. Welcome!", name)
相当于
var message string
message = fmt.Sprintf("Hi, %v. Welcome!", name)
Call your code from another module
In Go, code executed as an application must go in a main package. 所以calling side需要是一个main package
运行go mod init hello后,要改一改go.mod,让它能找到greetings module(因为我们没有真的发布greetings module,没有在example.com/greetings host它):
replace example.com/greetings => ../greetings
然后运行go build,它会创建出可执行文件,并给go.mod加上如下:
require example.com/greetings v0.0.0-00010101000000-000000000000
如果是用的published的module,会是这样:
require example.com/greetings v1.1.0
那我如果想自己指定用哪个版本的module呢?
Return and handle an error
package greetings
import (
"errors"
"fmt"
)
// Hello returns a greeting for the named person.
func Hello(name string) (string, error) {
// If no name was given, return an error with a message.
if name == "" {
return "", errors.New("empty name")
}
// If a name was received, return a value that embeds the name
// in a greeting message.
message := fmt.Sprintf("Hi, %v. Welcome!", name)
return message, nil
}
Take aways:
- 用errors package
- 可以return tuple
- nil
Caller code里,使用log package的log.Fatal(err)来print并终止运行
$ go build
$ ./hello
greetings: empty name
或者用go run,用go run可以看到exit status
$ go run hello
greetings: empty name
exit status 1
error是个interface,后面别的教程会讲到。
Return a random greeting
A slice is like an array, except that it's dynamically sized as you add and remove items.
formats := []string{
"Hi, %v. Welcome!",
"Great to see you, %v!",
"Hail, %v! Well met!",
}
后面别的教程会讲到slice,slice有个underlying array
还用到了math.rand package
Return greetings for multiple people
上小节讲了slice,这里讲了map
发现在hello folder里运行go build,如果它的dependency greetings moudle有改动,也会被build
Add a test
Go has built-in support for unit testing
命名规则,文件叫_test.go,case叫TestXXX。Also, test functions take a pointer to the testing package's testing.T as a parameter,用于reporting和logging
运行go test或go test -v
Compile and install the application
Discover the Go install path,用go list -f '{{.Target}}'
Add the Go install directory to your system's shell path,这样就可以直接run install了的程序了;或者可以改go install directory
然后运行go install
Matt:和我go build,然后得到的binary有区别吗?不知go build的结果,是不是已经包含了dependent package进去,试了一下能否挪动了再run,是可以的
A Tour of Go
https://tour.golang.org/welcome/1
实在写不下去了,CSDN的编辑器太难用了 😿