第一章 基本结构
1.1
go fmt helloworld.go //格式化代码,go在代码格式上采取强硬的态度
go run helloworld.go //直接运行该代码
go build helloworld.go //编译生成静态可执行文件,windows下生成 *.exe
go语言的完整组成部分
- package
- import
- 函数func,变量var,常量const,类型type
1.2命令行参数
os.Args变量是一个字符串(string)的切片(slice),其中os.Args[0], 是命令本身的名,其他参数保存在os.Args[1:len(os.Args)]中。
划重点
- go语言没有显示初始化,则被赋予零值
- go语言字符串连接使用
+
,与C++和js类似 - go语言
i++
是语句,不是表达式,所以j=i++
非法,++
,--
只能放在变量名后面,--i
也非法 - Go语言不允许使用无用的局部变量,需要忽略的变量使用
空标识符
(blank identifier),即_
(下划线) - 短变量声明只能用在函数内部,不能用于包变量
- 切片slice
[]int{1,2,3,4}
通过fmt.Println(slice[:])
会直接打印成[1 2 3 4]
for condition {}
代替 c语言中的while(condition){}
常用库及方法
os
os.Args[:]
fmt
fmt.Println("aaa")
fmt.Printf("%d\n", i)
strings
strings.Join([]string, string)
1.3查找重复的行
划重点
- map存储了键/值(key/value)的集合,键可以是任意类型,只要其值能用
==
运算符比较。 - map 的迭代顺序从实践来看是随机的,每次运行都会变化,这种设计是有意为之的。
- 以字母
f
结尾的格式化函数,如log.Printf
和fmt.Errorf
,都采用fmt.Printf
的格式化准则,f
指format。%v
表示任意类型默认格式值。
%d 十进制整数 %x, %o, %b 十六进制,八进制,二进制整数。 %f, %g, %e 浮点数: 3.141593 3.141592653589793 3.141593e+00 %t 布尔:true或false %c 字符(rune) (Unicode码点) %s 字符串 %q 带双引号的字符串"abc"或带单引号的字符'c' %v 变量的自然形式(natural format) %T 变量的类型 %% 字面上的百分号标志(无操作数)
- 以
ln
结尾的格式化函数,则遵循Println
的方式,以跟%v
差不多的方式格式化参数,并在最后添加一个换行符,ln
指line。 - 函数和包级别的变量可以任意顺序声明,并不影响其被调用。
- map 是一个由 make 函数创建的数据结构的引用。 map作为为参数传递给某函数时,该函数接收这个引用的一份拷贝,被调用函数对 map 底层数据结构的任何修改,调用者函数都可以通过持有的 map引用看到。(译注:类似于C++里的引用传递,实际上指针是另一个指针了,但内部存的值指向同一块内存)。
常用库及方法
io/ioutil
ioutil.ReadFile(string)
ioutil.WriteFile(string)
bufio
bufio.NewScanner(io.Reader) *Scanner
Scanner.Scan
Scanner.Text
os
os.Stdin
os.Stderr
os.File
os.Open
File.Close
File.Name
fmt
fmt.Fprintf(*File,"%v",err)
strings
strings.Split([]string, string)
- 内置函数
make
- 内置类型
error
nil
1.4GIF动画
划重点
- import包路径如image/color(image下的color包),只需要用最后那个单词表示。
- 目前常量声明的值必须是一个数字值、字符串或者一个固定的
boolean值。 - []color.Color{…}和gif.GIF{…}这两个表达式是复合声明,其中被赋值的的内部变量字段会被赋值,剩下的赋值各自类型的零值。
常用库及方法
math
math.Sin()
math.Pi
math/rand
rand.Float64()
image
image.Rect()
image.NewPaletted()
Paletted.SetColorIndex()
image/color
color.Color
color.White
color.Black
image/jpeg
image/gif
gif.GIF
gif.EncodeAll()
os
os.Stdout
1.5获取URL
划重点
- resp.Body.Close关闭resp的Body流,防止资源泄露
- os.Exit函数来终止进程,并返回一个status错误码,
其值为1
常用库及方法
net/http
http.Get(url)
resp.Body
resp.Body.Close()
os
os.Exit()
io
io.Copy()
strings
strings.HasPrefix()
1.6并发获取多个URL
划重点
- goroutine函数的并发执行方式,channel在goroutine之间传递参数。main也在一个goroutine中,go function新建一个goroutine,并执行这个函数。
- goroutine尝试在一个channel上做send或者receive时,这个goroutine会阻塞在调
用处,直到另一个goroutine往这个channel里写入、或者接收值,这样两个goroutine才会继续
执行channel操作之后的逻辑。 - 发送:(ch <- expression) 接收:(<-ch)
- 变量名可以与某个引用包名重复,但是不建议这样做
常用库及方法
fmt
fmt.Sprint(err)
time
time.Now()
time.Since(start).Seconds()
io
ioutil.Discard
os
os.Create()
1.7Web服务
划重点
- Go语言允许一个简单的语句结果作为循环的变量声明出现在if语句的最前面,下面这两段代码是等价的:
if err := r.ParseForm(); err != nil { log.Print(err) }
err := r.ParseForm() if err != nil { log.Print(err) }
常用库及方法
net/http
http.HandleFunc("/", handler)
http.ListenAndServer("localhost:8080", nilll)
http.ResponseWriter
r *http.Request
r.URL.Path
r.Method
r.URL
r.Proto
r.Header
r.Host
r.RemoteAddr
r.ParseForm()
r.Form
r.FormValue("key")
sync
sync.Mutex
log
log.Print
strconv
strconv.Atoi
本章要点
- 提及下switch的例子
switch coinflip() { case "heads": heads++ case "tails": tails++ default: fmt.Println("landed on edge!") }
- Go语言
switch()
不需要break
,会自动退出,显式地加fallthrough
语句来覆盖这种默认行为。 - Go语言里的
switch
还可以不带操作对象,则为switch true
,类似于if else
。
func Signum(x int) int { switch { case x > 0: return +1 default: return 0 case x < 0: return -1 } }
switch
也可以紧跟一个简短的变量声明,一个自增表达式、赋值语
句,或者一个函数调用。- 命名类型:
type Point struct { X, Y int } var p Point
- 指针:
&
操作符返回一个变量的内存地址,*
操作符获取指针指向的变量内容。Go语言里没有指针运算,也就是不能像c语言里可以对指针进行加或减操作。 - 方法和接口: 方法是和命名类型关联的一类函数。接口是一种抽象类型,这种类型可以让我们以同样的方式来处理不同的固有类型,不用关心它们的具体实现,而只需要关注它们提供的方法。
- 包(packages):Go语言编程大多数情况下就是用已有的package来写我们自己的代码。
- golang-pkg 和 go-doc 中找到标准库和社区写的package。
godoc
这个工具可以让你直接在本地命令行阅读标准库的文档。 - 多行注释可以用
/* ... */