所属分类:php教程
今天是周末的,虽然只有一天。给大家分享一个 Go1.17 的小快讯。一天增长一个吸鱼小技巧!
在 Go 语言中,一个切片(slice)包含了对其支持数组的引用,无论这个数组是作为一个独立的变量存在于某个地方,还是仅仅是一个为支持分片而分配的匿名数组。
其切片基本结构都如下:
// runtime/slice.go type slice struct { array unsafe.Pointer // 指向底层数组的指针 len int // 长度 cap int // 容量 }
目前切片这种支持数组的方式可能会导致切片出现有趣的内存泄漏或对你的切片产生令人惊讶的变化。
另外很重要的一点,在 Go 1.16 及以前,不存在将从切片类型转换为数组类型的安全方法,比较无奈。
我们只能通过调用标准库 reflect 或 unsafe,通过编写不安全的代码来做到这一点:
(*[10]byte)(unsafe.Pointer(&b[0]))
显然这是不优雅的,官方自己都不推荐使用 unsafe,一旦处理出错了,可能还会导致致命错误,比较不可控。
其实早在2009 年,在 Go 发布后不久(远在 Go 1.0 发布之前),就有人提出相关疑惑,希望解决这个问题:
php入门到就业线上直播课:进入学习
API 文档、设计、调试、自动化测试一体化协作工具:点击使用
终于,在即将到来的 Go 1.17 中,这将成为可能,因为从 commit-id #1c268431f4 开始的一系列变化,更新了规范:
新的规范中对此的描述很直接:
Converting a slice to an array pointer yields a pointer to the underlying array of the slice. If the length of the slice is less than the length of the array, a run-time panic occurs.
另外规范中提供了一些新的例子,在 Go1.17 中我们可以这么用:
s := make([]byte, 2, 4) s0 := (*[0]byte)(s) // s0 != nil s2 := (*[2]byte)(s) // &s2[0] == &s[0] s4 := (*[4]byte)(s) // panics: len([4]byte) > len(s) var t []string t0 := (*[0]string)(t) // t0 == nil t1 := (*[1]string)(t) // panics: len([1]string) > len(s)
需要注意,现在还没有办法像类型断言那样,检查他是否会因为越界等原因出现 panic 事件。如果你认为你可能有一个太短的片断,可能会导致 panic 事件,那么你需要使用 if 来进行预判断。
同时标准库 reflect 也会进行更新,以便于支持从切片到数组指针的转换,如果你正在用 reflect 做相关转换工作,建议阅读该提交中的注意事项。
你对 Go 语言在类型转换上有没有其它的一些想法和诉求,或者有没有踩过什么坑?
欢迎大家在评论区留言交流。
更多golang相关技术文章,请访问golang教程栏目!
以上就是有没有发现Go 1.17将允许切片转换为数组指针啦?的详细内容,更多请关注zzsucai.com其它相关文章!