That would work Kortschak. But this relies on a string's representation being the same as, but a bit smaller thabn, a []byte. I would prefer to use the Slice/StringHeader.
It's worth noting that _most_ of the problems I described in my initial post are hypothetical at this stage. The issue with strings being garbage collected mid-conversion are (I think) certain not to happen in Go 1.12 and the problems with storing a uinptr in a variable are mostly related to moving garbage collectors (so long as the location your uintpr points to doesn't get garbage collected). But both of these facts have a reasonable likely hood of changing in the future. The thing I would like the most is an pair of unsafe string <-> []byte conversion implementations which satisfy the rules of unsafe as they are written now which will _not_ compile if the representation of []byte/string changes in the future. This was what I thought I would get using the reflect.Slice/StringHeader structs and some unsafe. It's surprising that this doesn't work in a straight-forward way. On Saturday, September 21, 2019 at 8:11:08 AM UTC+2, kortschak wrote: > > func bytesToString(b []byte) string { > return *(*string)(unsafe.Pointer(&b)) > } > > https://play.golang.org/p/azJPbl946zj > > On Fri, 2019-09-20 at 13:30 -0700, Francis wrote: > > Thanks Ian, that's a very interesting solution. > > > > Is there a solution for going in the other direction? Although I > > excluded > > it from the initial post, it was only to reduce the size of the > > discussion. > > I would also like to implement > > > > func BytesToString(b []byte) string { > > > > I don't clearly see how to avoid using the StringHeader in this case. > > > > F > > > > On Wednesday, 18 September 2019 22:46:44 UTC+2, Ian Lance Taylor > > wrote: > > > > > > On Wed, Sep 18, 2019 at 2:42 AM Francis <francis...@gmail.com > > > <javascript:>> wrote: > > > > > > > > I am looking at the correct way to convert from a byte slice to a > > > > string > > > > > > and back with no allocations. All very unsafe. > > > > > > > > I think these two cases are fairly symmetrical. So to simplify > > > > the > > > > > > discussion below I will only talk about converting from a string to > > > []byte. > > > > > > > > func StringToBytes(s string) (b []byte) > > > > > > No reason to use SliceHeader, and avoiding SliceHeader avoids the > > > problems you discuss. > > > > > > func StringToBytes(s string) []byte { > > > const max = 0x7fff0000 > > > if len(s) > max { > > > panic("string too long") > > > } > > > return > > > (*[max]byte)(unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer( > > > &s)).Data))[:len(s):len(s)] > > > > > > } > > > > > > Of course, as you say, you must not mutate the returned []byte. > > > > > > Ian > > > > > > > > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/8bff6f8e-487a-4c69-a55e-513855d846da%40googlegroups.com.