golang易错点

Reader

  • 从Reader中读出数据,Reader里的数据会减少

chan

  • 给一个 nil channel 发送数据,造成永远阻塞
  • 从一个 nil channel 接收数据,造成永远阻塞
  • 关闭一个nil channel会触发panic
  • 关闭一个已关闭的管道会触发panic
  • 向一个已关闭的管道写入数据会触发panic
  • 从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个零值
  • 无缓冲的channel是同步的,而有缓冲的channel是非同步的

sync.WaitGroup

func main() {
	const N = 10
	var wg = &sync.WaitGroup{}
	
	for i := 0; i < N; i++ {
		wg.Add(1)			// add 1 goroutine to WaitGroup
		go func(i int) {
			println(i)
			defer wg.Done()	//a goroutine finished
		}(i)
	}
	wg.Wait()				//wait util all goroutines finish
}
  • 功能:等待线程全部结束
  • wg.Wait()将会阻塞,如果还有要等待的线程
  • wg.Add()增加需要等待的线程数量
  • wg.Done()等待的线程结束,即wg.Add(-1)

数据竞争

问题代码
total, sum := 0, 0
for i := 1; i <= 10; i++ {
    sum += i
    go func() {
        total += i
    }()
}
fmt.Printf("total:%d sum %d", total, sum)
解析
  • 主协程会很快退出,子协程没有执行
  • 数据竞争,多个子协程同时写total变量
  • “total += i” 中i的值是不确定的(不确定子协程会什么时候执行),执行时i很可能为11
改进代码
total,sum := 0,0
wg := sync.WaitGroup{}
mutex := sync.Mutex{}
for i := 0; i < 10; i++ {
	wg.Add(1)
	sum += i
	go func(i int) {
		mutex.Lock()
		total += i
		mutex.Unlock()
		wg.Done()
	}(i)
}
wg.Wait()
fmt.Printf("total:%d sum %d", total, sum)

2022-03-08 Marshaler接口

package main

import (
    "encoding/json"
    "fmt"
    "time"
)

func main() {
    t := struct {
        time.Time
        N int
    }{
        time.Date(2020, 12, 20, 0, 0, 0, 0, time.UTC),
        5,
    }

    m, _ := json.Marshal(t)
    fmt.Printf("%s", m)
}
/*******************
打印的结果:"2020-12-20T00:00:00Z"
分析:
  • time.Time实现了Marshaler接口,即MarshalJSON()。而time.Time是内嵌的,t就继承了time.Time的所有方法,包括MarshalJSON()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值