%T
: print type of variable
Create a slice:
sl1 := make([]string, 5);
sl2 := []int{1, 2, 3, 4, 5};
Append value to a slice:
sl1 = append(sl1, "string");
sl2 = append(sl2, 2, 3);
fmt.Println(len(sl2)); // 7
Create a map:
m1 = make(map[string]int)
m1["key"] = 1
m2 = map[string]int{"str": 1}
Delete key from a map:
delete m1["key"]
Check key is exist in a map:
value, isExist = m1["key"] // isExist = false
遍历map:
for key, value := range m2 {
fmt.Printf("%s -> %d", key, value)
}
定义:
type Human interface {
walk()
}
只要某个对象与 Interface
有相同的函数签名,我们就可以说该对象实现了 XX 接口。
空Interface即 interface{}
表示不包含任何 method
,即所有类型都实现该接口,相当于C语言中的 void *
。
断言变量的类型是否为 T
。
value, ok = element.(T)
// element是interface{}对象
// T是断言的类型
http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go
反射即检查程序在运行时的状态。
go someFunc()
默认情况下,channel
接收和发送数据都是阻塞的,除非另一端已经准备好,这样就使得Goroutines同步变的更加的简单,而不需要显式的lock。所谓阻塞,也就是如果读取(value := <-ch
)它将会被阻塞,直到有数据接收。其次,任何发送(ch<-5
)将会被阻塞,直到数据被读出。无缓冲 channel
是在多个 goroutine
之间同步很棒的工具。
func sum(a []int, c chan int) {
total := 0
for _, v := range a {
total += v
}
c <- total // send total to c
}
func main() {
a := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(a[:len(a)/2], c)
go sum(a[len(a)/2:], c)
x, y := <-c, <-c // 按顺序读取
fmt.Println(x, y, x + y)
}
channel默认无缓冲,故发送读取均会阻塞;如创建channel设定了buffer size,在buffer size以内可无阻塞写入。
func main() {
c := make(chan int, 2)
c <- 1
c <- 2 // 无阻塞写入
fmt.Println(<-c)
fmt.Println(<-c)
}
可使用 range
读取 channel
中的数据。
func fibonacci(n int, c chan int) {
x, y := 1, 1
for i := 0; i < n; i++ {
c <- x
x, y = y, x + y
}
close(c) // 必须在生产者中关闭channel!
}
func main() {
c := make(chan int, 10)
go fibonacci(cap(c), c)
for i := range c {
fmt.Println(i)
}
}
可用 select
来监听多个 channel
。
select
默认是阻塞的,只有当监听的channel中有发送或接收可以进行时才会运行,当多个channel都准备好的时候,select是随机的选择一个执行的。
func doSomething(normal, quit chan int) {
for {
select {
case normal <- 1:
// do something
case <- quit: // quit channel 接收到数据后退出
return // quit
}
}
}
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
A successful Copy returns err == nil, not err == EOF.
r := strings.NewReader("some io.Reader stream to be read\n")
if _, err := io.Copy(os.Stdout, r); err != nil {
log.Fatal(err)
}
CopyBuffer / CopyN:
func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)
func CopyN(dst Writer, src Reader, n int64) (written int64, err error)
Copy buffer/n btyes from src
to dst
.
NewReader, NewWriter, NewScanner
对 io.Reader
和 io.Writer
io.Scanner
的简易封装
https://godoc.org/bufio#NewReadWriter
You can custom scanner.Split func to control scan way
scanner scan reader by lines, if you want it to scan by words, see the following code:
const input = "123 3456 789"
scanner := bufio.NewScanner(strings.NewReader(input))
scanner.Split(bufio.ScanWords)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
// optional error handler
if err := scanner.Err(); err != nil {
fmt.Println(err)
}
Custom split function:
const input = "1,2,3"
splitComma := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
for i := 0; i < len(data); i++ {
if string(data[i]) == "," {
return i + 1, data[:i], nil
}
}
// return error if comma is not found
return 0, data, bufio.ErrFinalToken
}
scanner.Split(splitComma)
scanner := bufio.NewScanner(strings.NewReader(input))
for scanner.Scan() {
fmt.Println(scanner.Text())
// output:
// 1
// 2
// 3
}
Layout string: Mon Jan 2 15:04:05 MST 2006
即 星期一 一月二日下午三点四分五秒 2006年
t := time.Now()
t.Format("01-02 15:04:05") // 01-15 21:34:54
t2, err := time.Parse("15 04", "22 41"); // 0000-01-01 22:41:00 +0000 UTC
t.AddDate(year, month, day) // allow negative number
t.After(time) // check t is after `time` return boolean
t.Before(time) // check t is before `time` return boolean
math/rand
提供了伪随机数生成器。伪随机特性,种子不变,随机的结果就不会变。
rand.Intn(100) // 81
rand.Intn(100) // 87 重新运行程序也永远是这个数,伪随机特性,种子不变,随机的结果就不会变
自定义随机数种子:
source := rand.NewSource(time.Now().UnixNano())
rd := rand.New(source)
fmt.Printf("%d, %d", rd.Intn(100), rd.Intn(100)) // 重新运行程序结果改变,因为种子已经变化了
string to number:
val, err := strconv.Atoi("123") // val => 123
Http处理流程:
create http.Handler
:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
or using http.HandleFunc
:
func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
gorilla/mux - A powerful URL router and dispatcher for golang.