go学习笔记

time.NewTicket 疑问点记录:

package main

import (
	"fmt"
	"time"
)


func main() {
	ticker := time.NewTicker(time.Second)
	intChan := make(chan int, 1)
	go func() {
		for _ = range ticker.C {
			select {
			case intChan <- 1:
			case intChan <- 2:
			case intChan <- 3:
			}
		}
		fmt.Println("send ending")
	}()
	sum := 0
	for ele := range intChan {
		fmt.Printf("receive element %d from intChan \n", ele)
		if sum > 10 {
			break
		}
		sum += ele
	}
	fmt.Printf("sum %d \n", sum)
}

输出结果:
在这里插入图片描述
为什么: send ending 没有输出????
我的理解是:
go func 中开启的是周期性定时器,理论上如果主协程不结束,该协程会一直运行。
也就是会一直执行for 语句,当主协程停止时,该协程自然也停止,所以不会执行send ending

合理的切片拷贝操作

// Endpoints lists the registered endpoints for the client.
func (c *Client) Endpoints() []string {
	// copy the slice; protect original endpoints from being changed
	// 复制片;保护原始endpoints不被更改
	c.mu.RLock()
	defer c.mu.RUnlock()
	eps := make([]string, len(c.cfg.Endpoints))
	copy(eps, c.cfg.Endpoints)
	return eps
}

以上是在查看etcd 源码时的收货,注释很详细,大家可以参考着用

对互斥锁进行多次解锁

package main

import (
	"fmt"
	"sync"
)

func main() {
	defer func() {
		fmt.Println("try to recover the panic")
		if p:= recover();p != nil{
			fmt.Printf("recover the panic :%#v \n",p)
		}
	}()
	var lock sync.Mutex
	lock.Lock()
	fmt.Println("has locked")
	lock.Unlock()
	fmt.Println("has unlocked")
	fmt.Println("try to unlocked again")
	lock.Unlock()
}

执行结果为:

has locked
has unlocked
try to unlocked again
fatal error: sync: unlock of unlocked mutex

goroutine 1 [running]:
runtime.throw(0x4d3e7a, 0x1e)
        E:/language/go/sdk/go1.14.3/src/runtime/panic.go:1116 +0x79 fp=0xc000071ea8 sp=0xc000071e78 pc=0x432529
sync.throw(0x4d3e7a, 0x1e)
        E:/language/go/sdk/go1.14.3/src/runtime/panic.go:1102 +0x3c fp=0xc000071ec8 sp=0xc000071ea8 pc=0x43249c
sync.(*Mutex).unlockSlow(0xc0000140a0, 0xc0ffffffff)
        E:/language/go/sdk/go1.14.3/src/sync/mutex.go:196 +0xdd fp=0xc000071ef0 sp=0xc000071ec8 pc=0x46ec4d
sync.(*Mutex).Unlock(...)
        E:/language/go/sdk/go1.14.3/src/sync/mutex.go:190

很奇怪,发现并没有recover住,翻阅资料得知,在GO1.8之前是可以recover住的,但是会导致重复解锁的goroutine永久阻塞,所以1.8之后对这类型的panic变成了不可恢复

工具类

时间相关

获取给定时间戳的零点

func GetZeroPointTime(data int64) time.Time {
	timeStr := time.Unix(int64(data), 0).Format("2006-01-02")
	loc, _ := time.LoadLocation("Local")
	t, _ := time.ParseInLocation("2006-01-02", timeStr, loc)
	return t
}

golang内存对齐

https://zhuanlan.zhihu.com/p/53413177

将UTC字符串时间转换成时间戳

// ConvertUTCStr 将UTC时间转换成时间戳
func ConvertUTCStr(utcStr string) (int64, error) {
	stamp, err := time.ParseInLocation(time.RFC3339, utcStr, time.Local) //使用parseInLocation将字符串格式化返回本地时区时间
	if err != nil {
		return 0, err
	}
	return stamp.Unix(), nil
}

将当前时间戳转成UTC时间字符串

// CoverTs2Utc 将指定时间戳转换成 UTC 时间字符串
// 阿里云API 关于时间的参数,都可以使用该函数
func CoverTs2Utc(ts int64) (string, error) {
	if ts <= 0 {
		return "", fmt.Errorf("invalid timestamp:%d", ts)
	}
	t := time.Unix(ts, 0)
	local, err := time.ParseInLocation(time.RFC3339, t.Format(time.RFC3339), time.Local)
	if err != nil {
		return "", fmt.Errorf("ParseInLocation failed:%s", err.Error())
	}
	utc := local.UTC()
	utcStr := utc.Format(time.RFC3339)
	return utcStr, nil
}
// 测试
func main (){
     // 输出内容 2021-08-23T12:26:36Z
	fmt.Println(CoverTs2Utc(time.Now().Unix()))
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值