Go踩过的坑(杂)

Go踩过的各种小坑总结

2019-04-18  本文已影响0人  哥斯拉啊啊啊哦
(坑1)chan的内部实现已经类似指针了。chan即使作为值传递拷贝一份给别人,
两个chan还是会“指向”同一个物理的channel。
从channel获取数据的两种写法
a := make(chan int)
(1) v := <- a     (2) v :=range a

//某些情况下channel必须由缓存区才能传送数据,比如以下情况
func main() {
    out := make(chan []int, 0)

    a := []int{55, 5, 6}
    fmt.Println(a)
    out <- a
    fmt.Println(out)
    close(out)

    for v := range out {
        fmt.Println(v)
    }
}
// chan 后面没缓冲区,这样执行会报错
[55 5 6]
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:

// 改成至少由1个缓冲区才不会报错
func main() {
    out := make(chan []int, 1)

    a := []int{55, 5, 6}
    fmt.Println(a)
    out <- a
    fmt.Println(out)
    close(out)

    for v := range out {
        fmt.Println(v)
    }
}
// 这样就能正确输出
[55 5 6]
0xc000074120
[55 5 6]
(坑2)go语言没有字符型,只有rune类型,rune是int32的一个别名,所以
字符和int是可以通用的,打印时采用%c,就可以按照字符来打印。
%c是输出单个字符
(坑3)两个数组元素加在1个数组的快捷方法
a:=[]interfere{}{5,6,9,3}    b:=[]int{9,8,3,4}
a=append(a, b...) 
b后面加...,意思就是把b的元素展开来,一个一个加到a里面
输出结果是[5,6,9,3,9,8,3,4]

如果不加...,输出结果是
[ [5,6,9,3], [9,8,3,4] ],就变成2个数组了
(坑4)指针赋值等于指向相同地址的指针,其中一个改变,另外一个也跟着改变,如下面
//
func main() {
    a := new(int)
    b := a
    *a = 50
    fmt.Println(*a, *b)
    *b = 30
    fmt.Println(*a, *b)
}
输出结果为
50 50
30 30
(坑5) 结构指针&{nil,nil} 不等于 nil
//
func main() {
    a := new(hello)

    fmt.Println("a 为:", a)
    fmt.Println("a 和 nil 是否相等:", a == nil)
}
// 输出结果
a 为: &{<nil> <nil>}
a 和 nil 是否相等: false
(坑6)*[]int  是一个数组指针,元素类型为 int
        []*int  是一个数组值,元素类型为 *int
//
(坑7)字符串的简单拼接
func main() {
    a := "hahah--"
    b := "heihei--"

    c := a + b
    fmt.Println(c)

    c = a[3:] + b[:5]
    fmt.Println(c)
}
// 输出结果
hahah--heihei--
ah--heihe
(坑8)
//
如果不初始化 map,那么就会创建一个 nil map, nil map 不能用来存放键值对
map 的键可以是任意内建类型或者是 struct 类型,map 的值可以是使用 ==操作符的表达式
slice,function 和 包含 slice 的 struct 类型不可以作为 map 的键,否则会编译错误:
map 的值可以是 slice 或者另一个 map。slice 和 func 不能作为 map 的键
在函数之间传递 slice 和 map 是相当廉价的,因为他们不会传递底层数组的拷贝
(坑9)结构体也有数组啊,之前有点下意识的忽略了,只跟map联系在一起
//
type wc struct {
    Name string
    wcs  []*wc
}

func main() {
    q := [10]wc{}
    fmt.Println(q)
    fmt.Println(q[5])
}
输出
[{ []} { []} { []} { []} { []} { []} { []} { []} { []} { []}]
{ []}
(坑10)go的底层实现中,访问连续的内存地址,速度要比索引访问内存地址快许多,
如遍历sliec,和通过i索引访问slien[i],都遍历一遍,前者速度要快于后者
//
(坑11)golang中可以之间用 ==, <, >, <=, >=比较字符串大小
// 字符串比较大小的规则暂时不清楚,不过可以利用这点用平衡树建立来map,这样能从小到大
输出数据,比golang自带的map功能多
json的反序列化方式有两种:

Use json.Unmarshal passing the entire response string
// func Unmarshal(data []byte, v interface{}) error
data, err := ioutil.ReadAll(resp.Body)
if err == nil && data != nil {
    err = json.Unmarshal(data, value)
}

using json.NewDecoder.Decode
// func NewDecoder(r io.Reader) *Decoder
// func (dec *Decoder) Decode(v interface{}) error
err = json.NewDecoder(resp.Body).Decode(value)

这两种方法看似差不多,但有不同的应用场景
上一篇 下一篇

猜你喜欢

热点阅读