这里记录一些平时学到的一些离散的Golang技巧。

  1. 当搞不清把Slice变量当参数应该传它的指针还是值的时候,看看下面这段代码:
package main

import "fmt"

func main() {
    s := []string{"a", "b"}
    fmt.Println(testPassValue(s))    // [b]
    fmt.Println(s)                   // [a b]
    fmt.Println(testPassAddress(&s)) // [b]
    fmt.Println(s)                   // [b]
}

func testPassValue(s []string) []string {
    s = s[1:]
    return s
}

func testPassAddress(s *[]string) []string {
    *s = (*s)[1:]
    return *s
}
  1. 当用copy函数进行两个slice赋值的时候,应该先为目标slice分配和源slice一样大小的数组空间:
// copy x to y, type of both x and y is []int
y = make([]int, len(x), cap(x))
copy(y, x)
  1. map 类型的变量使用前应该用map literal或者make初使化:
var m map[string]int

m = map[string]int{ ... }  // keys is requried

m = make(map[string]int) // make
  1. 得益于slice,用golang实现栈或者对列非常简单。我们先来看栈的实现:
stack := []string{}

stack = append(stack, "elem")  // push one element to stack
top := stack[len(stack)-1]  // get the top element of stack
stack = stack[:len(stack)-1] // pop one element from stack

再来看对列的实现:

queue := []string{}

queue = append(queue, "elem") // push one element to queue
top := queue[0] // get the top element of queue
queue = queue[1:] // pop one element from queue
  1. 在golang中,一个类型的变量是可以调用对应类型的方法(Method)的。如下面的代码:
package main
import "fmt"

type myInt int

func main() {
    var i, j myInt
    i.changeValue(3)
    j.changeNothing(5)
    fmt.Println(i, j) // i: 3 j: 0
}

func (mi *myInt) changeValue(val myInt) {
    *mi = val
}

func (mi myInt) changeNothing(val myInt) {
    mi = val
}

  1. 在golang中for循环的第二个参数是值传递的方式,不能用于修改原变量的值。如果 想要修改原变量的值,可以用for的第一个参数,对原数据进行下标访问。如:
var a []int{1, 2, 3}
for _, item := range a {
    item += 1
}
fmt.Println(a) // a: 1, 2, 3 数据没有发生变化

for i := range a {
    a[i] += 1
}
fmt.Println(a) // a: 2, 3, 4 数据发生变化
  1. 为结构体fields加上两种格式tag的方法如下:
type Person struct {
    Name string `xml:"Name,omitempty" json:"Name,omitempty"`
    Age  int `xml:",omitempty" json:",omitempty"`
}
  1. \r escape characters 可以将输出位置移到当前所在行的开头,下面是它的一个例子,我们 可以用它来实现一个 spinner:
func spinner(delay time.Duration) {
    for {
        for _, r := range `_\|/` {
            fmt.Printf("\r%c", r)
            time.Sleep(delay)
        }
    }
}

以上。