Golang 速查表
Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型、编译型语言。Go 语言语法与 C 相近,但功能上有:内存安全,GC(垃圾回收),结构形态及 CSP-style 并发计算。
Hello world
package main
import "fmt"
func main() {
message := greetMe("world")
fmt.Println(message)
}
func greetMe(name string) (string) {
return "Hello, " + name + "!"
}
$ go build
变量
变量声明
var msg string
msg = "Hello"
缩写
msg := "Hello"
常量
const Phi = 1.618
常量可以是字符、字符串、布尔值或数值。
基础类型
字符串
str := "Hello"
str := `Multiline
string`
字符串的类型是string。
数值
典型类型
num := 3 // int
num := 3. // float64
num := 3 + 4i // complex128
num := byte('a') // byte (alias for uint8)
其他类型
var u uint = 7 // uint (unsigned)
var p float32 = 22.7 // 32-bit float
指针
func main () {
b := *getPointer()
fmt.Println("Value is", b)
}
func getPointer () (myPointer *int) {
a := 234
return &a
}
指针指向变量的内存位置。Go是完全垃圾收集。
数组
// var numbers [5]int
numbers := [...]int{0, 0, 0, 0, 0}
数组的大小是固定的。
切片
slice := []int{2, 3, 4}
slice := []byte("Hello")
与数组不同,片具有动态大小。
流程控制
条件判断
if day == "sunday" || day == "saturday" {
rest()
} else if day == "monday" && isTired() {
groan()
} else {
work()
}
if 中的语句
if _, err := getResult(); err != nil {
fmt.Println("Uh oh")
}
if 语句可以在条件表达式前执行一个简单的语句
Switch
switch day {
case "sunday":
// cases don't "fall through" by default!
fallthrough
case "saturday":
rest()
default:
work()
}
函数
Lambdas
myfunc := func() bool {
return x > 10000
}
函数是第一类对象。
多个返回类型
a, b := getMessage()
func getMessage() (a string, b string) {
return "Hello", "World"
}
指定返回值
func split(sum int) (x, y int) {
x := sum * 4 / 9
y := sum - x
return
}
通过在声明返回值名称,return(没有参数)将返回具有这些名称的变量。
包
加载
import "fmt"
import "math/rand"
import (
"fmt" // gives fmt.Println
"math/rand" // gives rand.Intn
)
Both are the same.
别名
import r "math/rand"
r.Intn()
调用名称
func Hello () {
···
}
调用名称以大写字母开头。
Packages
package hello
每个包文件都必须从包开始。
并发
Goroutines
func main() {
// A "channel"
ch := make(chan string)
// Start concurrent routines
go push("Moe", ch)
go push("Larry", ch)
go push("Curly", ch)
// Read 3 results
// (Since our goroutines are concurrent,
// the order isn't guaranteed!)
fmt.Println(<-ch, <-ch, <-ch)
}
func push(name string, ch chan string) {
msg := "Hey, " + name
ch <- msg
}
通道是并发安全的通信对象,在goroutines中使用。
缓冲通道
ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3
// fatal error:
// all goroutines are asleep - deadlock!
缓冲通道限制了它可以保存的消息的数量。
关闭通道
Closes a channel
ch <- 1
ch <- 2
ch <- 3
close(ch)
遍历一个通道,直到它关闭
for i := range ch {
···
}
Closed if ok == false
v, ok := <- ch
错误控制
Defer
func main() {
defer fmt.Println("Done")
fmt.Println("Working...")
}
将函数的运行延迟到其周围的函数返回。这些参数立即被求值,但是函数调用直到最后才运行。
延迟函数
func main() {
defer func() {
fmt.Println("Done")
}()
fmt.Println("Working...")
}
Lambdas更适合延迟块。
结构体
定义
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v.X, v.Y)
}
字面量
v := Vertex{X: 1, Y: 2}
// Field names can be omitted
v := Vertex{1, 2}
// Y is implicit
v := Vertex{X: 1}
您还可以输入字段名。
指向结构体的指针
v := &Vertex{1, 2}
v.X = 2
当v是指针时,执行v.X和(*v)是一样的。
方法
接收器
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X * v.X + v.Y * v.Y)
}
v: = Vertex{1, 2}
v.Abs()
没有类,但是您可以使用接收器来定义函数。
更改
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.y = v.Y * f
}
v := Vertex{6, 12}
v.Scale(0.5)
// `v` is updated
通过将接收器定义为指针(*Vertex),您可以进行更改。