求教大神,在Golang Go语言中如果想学会怎么使用 unsafe 这个包...该怎么学...

发布于 1周前 作者 ionicwang 来自 Go语言

求教大神,在Golang Go语言中如果想学会怎么使用 unsafe 这个包…该怎么学…
以下的代码说实在,看不懂…
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
}


更多关于求教大神,在Golang Go语言中如果想学会怎么使用 unsafe 这个包...该怎么学...的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

先通过反射获取空接口变量的类型 检查是否为 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 语言 看这些就容易很多了

更多关于求教大神,在Golang Go语言中如果想学会怎么使用 unsafe 这个包...该怎么学...的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


垃圾代码,要是 chan 的实现变了,这个代码就会无声无息地返回错误结果。
不用学,免得写出这种半桶水的东西坑别人。

在Golang中,unsafe包是一个提供绕过类型安全操作的特殊包,学会使用它需要一定的专业知识和谨慎态度。以下是一些学习建议:

  1. 阅读官方文档:首先,应仔细阅读Golang官方文档中关于unsafe包的部分,这是理解其功能和用法的最佳起点。官方文档详细解释了unsafe包中的各个类型和函数,以及它们的使用场景和潜在风险。
  2. 学习基本用法:通过实际编写代码来掌握unsafe包的基本用法。例如,学习如何进行指针类型转换、访问和修改结构体私有成员变量,以及实现[]byte和字符串之间的零拷贝转换等。
  3. 深入理解内存布局:要深入理解Go语言的内存布局和指针操作原理,这对于正确使用unsafe包至关重要。了解slice、string等底层结构有助于理解如何通过unsafe包进行高效的内存操作。
  4. 谨慎使用:由于unsafe包可能会破坏Go语言的类型安全性和内存安全性,使用时需要特别小心。避免在生产环境中使用unsafe包,除非确信其带来的性能提升远大于潜在的风险。

总之,学习unsafe包需要耐心和细心,务必在充分理解其原理和风险的前提下进行实践。

回到顶部