(Just as an aside: please don't post screenshot images. Plaintext is easier to read and can be copy-pasted. You can also use https://go.dev/play/ to paste code snippets)
I think you have understood the issue well. From the source code at https://golang.org/src/runtime/slice.go : type slice struct { array unsafe.Pointer len int cap int } As you have found, this is passed by value. You can of course pass a pointer to such a value explicitly, if you choose. > Is it a *trap*?! Well, it's something you have to learn about the language, but I think it's the best choice out of the design options which were available. Strings and slices are consistent with each other: they are plain structs, containing pointer to data, length, and (for slices) capacity. Could slices and strings have been implemented so that their value is always a *pointer* to a structure? I guess so, but I think you would still end up with a similar problem at a deeper level. When you copy a slice (b := a), or pass it as a function argument, then you'd be copying a pointer, so you'd have two aliases to the same slice, and modifications to one would be visible to the other. But when you sub-slice (b := a[1:2]) then you'd be forced to allocate a new slice structure. The behaviour of a slice therefore would be dependent on exactly how it was generated, and so mutating a slice *may or may not* affect other slices. I think would be more confusing overall. On top of that, you'd still have the same problem which you have today: two slices *may or may not* share the same underlying buffer. Maps and channels are consistent with each other: they have a large data structure, and the value is a pointer to that structure. I think there is a very good reason for making map values be pointers; it means you can do convenient things like m["foo"] = "bar" instead of m = m.set("foo", "bar") // compare: s = append(s, "foo") But on the flip side, the zero value of a map or channel is not very useful: it's a nil pointer, which tells you that have zero elements, but you cannot add any elements. This makes them inconvenient when building a structure which contains these things, because you need to make(...) the values explicitly. This is something else that newcomers to Go have been known to complain about. On Thursday, 17 March 2022 at 13:47:17 UTC qizo...@gmail.com wrote: > Why does Go's slice has '*replication trap*', but map does not? > Suppose we have a function that takes slice as an input parameter, and if > slice is *expanded* in the function, only the copied slice structure is > changed, instead of the original slice structure. The original slice still > points to the original array, and the slice in the function has changed the > array pointer because of the expansion. > [image: 111.png] > Look at the output, if slice is passed by 'reference', it won't be like [1 > 2]. > [image: 222.png] > Look at this, the operation we've done in domap() worked! > Is it a *trap*?! > I mean, map is passed by 'reference'(*hmap) and slice is passed by > 'value'(SliceHeader). > Why is it that map and slice are designed to be all inner *referenced* > types and why is it so *inconsistent*? > Maybe it's just a design question, but why? Why slice and map like that? > > ---------------------------------------------------------------------------------------------------------------------------------------------- > Below is my guess about proving why map can only be passed by 'reference': > > Assume that map is passed by value -> hmap struct type > (1) After Init: (hmap *outside* the function) > *hmap.buckets = bucketA* > *hmap.oldbuckets = nil* > (2) After passing the param, entering the function: (hmap *inside* the > function) > *hmap.buckets = bucketA* > *hmap.oldbuckets = nil* > (3) After triggering the expanding: (hmap *inside* the function) > *hmap.buckets = bucketB* > *hmap.oldbuckets = bucketA* > > But slice is *different*! > > There is no incremental migration, and there is *no oldbuckets*, so you > can use a structure because the function is *isolated* from the outside, > whereas map is not, and oldbuckets are referenced outside the function. > > I mean, the original purpose of this design may be *passing value*, to > *prevent > direct modification of the original variable* in the function, but map > cannot be passed by value. Once the value is passed to the map, the > original map data will be lost during the expansion of the function. > > ---------------------------------------------------------------------------------------------------------------------------------------------- > I will appreciate that if some one can help me solve this problem. Thanks > a lot! > (I feel sorry for my poor Chinglish, I hope I described this well...:( It > really troubled me a lot...) > -- 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/7d8ac331-0b95-4fa5-9f89-3ca4ce558bb6n%40googlegroups.com.