search [160f119621ba22 brain into fried fish ] Follow this fried fish with liver-fried liver. This article GitHub github.com/eddycjy/blog has been included, and there are my series of articles, materials and open source Go books.
Hello everyone, I am fried fish.
Today is the weekend, although there is only one day. To share with you a small news about Go1.17. Add a fish-sucking trick a day!
In the Go language, a slice contains a reference to its supporting array, whether the array exists somewhere as an independent variable or just an anonymous array allocated to support the slice.
The basic structure of the slice is as follows:
// runtime/slice.go
type slice struct {
array unsafe.Pointer // 指向底层数组的指针
len int // 长度
cap int // 容量
}
The current way of slicing this support array may cause interesting memory leaks or surprising changes to your .
Another important point is that in Go 1.16 and before, there is no safe way to convert from a slice type to an array type, which is rather helpless.
We can only do this by calling the standard library reflect or unsafe, and by writing unsafe code:
(*[10]byte)(unsafe.Pointer(&b[0]))
Obviously this is not elegant, the official does not recommend the use of unsafe, once a processing error, it may lead to fatal errors, more uncontrollable.
In fact, as early as 2009, shortly after the release of Go (far before the release of Go 1.0), some people raised related doubts, hoping to solve this problem:
Finally, in the upcoming Go 1.17, this will be possible because of a series of changes starting from commit-id #1c268431f4, and the specification is updated:
The description of this in the new specification is straightforward:
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.
- If the length of the slice is longer than the length of the array, it is harmless and works normally.
- If the slice is longer than the array, it means that your array will not be able to access all the supporting arrays of the original slice.
In addition, some new examples are provided in the specification. We can use this in 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)
- The conversion of variable s2: It converts the array at the bottom of the slice. This conversion does not (and cannot) allocate a new array, thus ensuring its efficiency.
- Conversion of variables s0 and t0: It converts a non-empty segment into a zero-length array. Although you can't do anything with an array of length 0, you still have to give a valid pointer, which is nil.
It should be noted that there is currently no way to check whether a panic event occurs due to out-of-bounds and other reasons like type assertions. If you think you may have a short segment that may cause a panic event, then you need to use if to make a prejudgment.
At the same time, the standard library reflect will also be updated so that supports the conversion from slice to array pointer . If you are using reflect for related conversion work, it is recommended to read the notes in this submission.
Do you have any other thoughts and demands on the type conversion of Go language , or have you stepped on any pits?
Welcome everyone to leave a message in the comment area.
If you have any questions please comment and feedback exchange area, best relationship is mutual achievement , everybody thumbs is fried fish maximum power of creation, thanks for the support.
The article is continuously updated, and you can read it on [My brain is fried fish], and reply [160f119621bcd7 000 ] I have prepared the first-line interview algorithm questions and information; this article GitHub github.com/eddycjy/blog has been included , Welcome Star to urge you to update.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。