求教大神,如果想学会怎么使用 unsafe 这个包...该怎么学...

2019-08-20 20:51:20 +08:00
 hucs2542
以下的代码说实在,看不懂...
import (
"unsafe"
"reflect"
)

func isChanClosed(ch interface{}) bool {
if reflect.TypeOf(ch).Kind() != reflect.Chan {
panic("only channels!")
}
cptr := *(*uintptr)(unsafe.Pointer(
unsafe.Pointer(uintptr(unsafe.Pointer(&ch)) + unsafe.Sizeof(uint(0))),
))

// this function will return true if chan.closed > 0
// see hchan on https://github.com/golang/go/blob/master/src/runtime/chan.go
// type hchan struct {
// qcount uint // total data in the queue
// dataqsiz uint // size of the circular queue
// buf unsafe.Pointer // points to an array of dataqsiz elements
// elemsize uint16
// closed uint32
// **

cptr += unsafe.Sizeof(uint(0))*2
cptr += unsafe.Sizeof(unsafe.Pointer(uintptr(0)))
cptr += unsafe.Sizeof(uint16(0))
return *(*uint32)(unsafe.Pointer(cptr)) > 0
}
2236 次点击
所在节点    Go 编程语言
2 条回复
vy0b0x
2019-08-21 02:02:36 +08:00
先通过反射获取空接口变量的类型 检查是否为 channel
确认是 channel 之后获取此变量在内存中的位置 也就是制造了一个指针

注释是 channel 的数据结构
unsafe.Sizeof(uint(0))*2 是跳过 qcount 和 dataqsiz
unsafe.Sizeof(unsafe.Pointer(uintptr(0))) 是跳过 buf
unsafe.Sizeof(uint16(0))是跳过 elemsize
*(*uint32)(unsafe.Pointer(cptr))取得结构中 closed 地址的数据 检查是否大于 0

可以先学 c 语言 看这些就容易很多了
reus
2019-08-24 09:07:03 +08:00
垃圾代码,要是 chan 的实现变了,这个代码就会无声无息地返回错误结果。
不用学,免得写出这种半桶水的东西坑别人。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/593635

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX