4 ms·
I dislike the fact that the value in range over a slice is a copy, rather than an alias, to the slice value. It seems to me to be strictly less useful than the
by jbert 13y ago
I dislike the fact that the value in range over a slice is a copy, rather than an alias, to the slice value.
It seems to me to be strictly less useful than the alternative (aliasing).
And I also don't really buy the argument that "it is a normal assignment and so has to copy", since:
i, v := range s
isn't a normal assignment. It has special rules to do with looping. Having the additional rule that v aliases to the entry seems to me to be a full win (too late to change now I guess).
- JulianMorrison 13y agoThe reason it's right is that if it was done by aliasing, it would create a wierd trap variable, an invisible pointer dereference which would modify something else. a := 1 b := []int{2,3,4} for i, c := range b { // lots more code a = 5 c = 6 // now a is 5 and c is 6 as you'd expect // but also by magic, b[i] is 6 } // now by magic, b is {6,6,6}
- peterarmitage 13y agoThis catches people out, and is something that some people on the Go team have expressed regret over - unfortunately it is too late to change due to backwards compatibility promises. http://youtu.be/p9VUCp98ay4?t=22m18s http://youtu.be/p9VUCp98ay4?t=22m18s http://golang.org/doc/go1compat.html http://golang.org/doc/go1compat.html
- peterarmitage 13y agoSorry, I misread your comment, this isn't relevant.
- peterarmitage 13y agoSorry, I misread your comment, this isn't relevant.
- BarkMore 13y agoThe Go Team regrets defining the scope of the range variables as the for statement. I am not aware of any regrets regarding the alias issue. The range variable scope is the one big gotcha that's missing from the article. See http://golang.org/doc/faq#closures_and_goroutines http://golang.org/doc/faq#closures_and_goroutines for one discussion of the issue.
- kybernetyk 13y agoThough I like the copy behavior more than the reference one I wish there was an option to turn on aliasing. Kinda like in C++11's for(:) where you can get both - a copy or a reference. Having strict control over reference/value semantics is a feature I don't want to miss in a systems language.
- THens 13y agoYep, I suppose this would be the preferable way to deal with this whole situation, although it might confuse new Go programmers and it may produce nasty bugs which are rather hard to find (especially in a larger code base, obviously).
- dualogy 13y agoIt's not just "too late to change now", it's also proper behavior. Go code is meant to be concise: - once a Go developer learned that the above is a copy (which she will learn very early on), she won't ever forget, it's just too fundamental - to modify the slice, just modify the slice and skip the copy with underscore: for i, _ := range mySlice { mySlice[i] = "foo" } There we go. Syntax simplicity (without exotic compiler flags or prep directives) and conciseness fully preserved.
- neeee 13y agoBy the way, you don't need a _ assignment there. You can just do i := range mySlice.
- pkulak 13y agoWhich I still do constantly, then get a compile error when what I thought was something else is actually an int.
- dualogy 13y agoThat's a good reason to always include both parts of the LHR: because if that "something else" actually is an int -- then you'll have a nasty bug at your hands (and not a compiler-catchable one at that).