On Tuesday, November 10, 2020 at 9:41:09 PM UTC+11 Jan Mercl wrote:
Thank you for taking the time to answer, I'm still a little confused and have inlined where that confusion is below. On Tue, Nov 10, 2020 at 11:09 AM shan...@gmail.com <shan...@gmail.com> > wrote: > > > My confusion is this, the comment says (very clearly) > > It's not safe, nor portable, and may change (although I have had it > pointed out to me that the comparability guarantee may contradict this) > > It does not. When there exists explicit documentation for the > contrary, it means the contrary. > > Sorry, because you quoted the whole string I am confused what you mean (on reflection I am thinking you are just saying that the documentation is contrary to the compatibility guarantee and as such the sliceheader is not subject to that guarantee) > > Further the Data field reference won't stop the Garbage collector > removing the data > > It's the same as for any other uintptr anywhere else. It's not a > pointer and thus does not guarantee reachability of its "pointee". The > documentation just reminds of this. > > Ah, yes I see what you mean > So, can someone explain to me what it's purpose in life is (there's > suggestion that it was a temporary fix that, like all things temporary, has > become permanent, and if so, I wonder if that means the documentation needs > updating) > > This does not make reflect.SliceHeader unusable though. The > reflect.SliceHeader is either aliased to a real slice or is later > unsafely converted to one. Then the uintptr field is no more an > uintptr, but a real pointer. The documentation points out that _in > between_ one has to guarantee the reachability by other means, the > only pseudo-reference of the uintptr value is not sufficient for that. > > So, the only two uses I have found for this is 1) A Teaching aid, showing people what a slice is under the hood 2) This piece of code that I have just found that converts/moves a C array into a Go slice ``` func getArr(which int) []byte { var theCArray *C.char = C.getTheArray(C.int(which)) length := int(C.BLOCKSIZE) var theGoSlice []byte sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&theGoSlice))) sliceHeader.Cap = length sliceHeader.Len = length sliceHeader.Data = uintptr(unsafe.Pointer(theCArray)) // now theGoSlice is a normal Go slice backed by the C array return theGoSlice } ``` Are there other uses? I see nothing in the documentation that needs to be updated. It's > possible that it could be improved to become better understood as it > seems it's not always working that way. > I think it does need some attention for clarity, I'm still a little confused what exactly it's trying to convey (The way it's written, to me at least, says, don't use this because it's unsafe, non-portable, and may change) One other bone of contention the term "sliceheader" appears only in the reflect package. But https://blog.golang.org/slices uses the term liberally to refer to an example slice struct that appears to be like the one found in https://github.com/golang/go/blob/master/src/runtime/slice.go#L13 I *know* this is nit picking, but I feel that the blog should be clear that the term is purely informal, a number of times I have been told that that use of the term in the blog means that is what the struct is officially called -- 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/8cafdfbf-7973-4a29-a160-06e72d0ff7bdn%40googlegroups.com.