You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I spend some time to realize that by getting a value from a map we get a copy instead a reference. So when we need to do an accumulator it will be fail if we try to update just the copy. Seems documentation is not clear about this:
It's also possible to use an or {} block to handle missing keys:
You can also check, if a key is present, and get its value, if it was present, in one go:
I went to the docs to check how to detect a missing key but it doesn't say that the value found is a copy. The same happens using if/else or or { } forms. Next program show the difference:
structAccumulator {
mut:
data map[string][]int
}
fn (mut a Accumulator) push_fail(key string, value int) {
ifmutcopy:= a.data[key] {
copy << value
} else {
a.data[key] = [ value ]
}
}
fn (mut a Accumulator) push_ok(key string, value int) {
if_:= a.data[key] {
a.data[key] << value
} else {
a.data[key] = [ value ]
}
}
fnmain() {
mutok:= Accumulator{}
mutbad:= Accumulator{}
for number in [ 1, 2, 3, 4, 5 ] {
key:=if number %2==1 { 'odd' } else { 'even' }
ok.push_ok(key, number)
bad.push_fail(key, number)
}
println('ok ${ok}')
println('bad ${bad}')
}
Produces
ok Accumulator{
data: {'odd': [1, 3, 5], 'even': [2, 4]}
}
bad Accumulator{
data: {'odd': [1], 'even': [2]}
}
I think, that it may be a bug, i.e.: if mut x := a.data[key] { should produce a reference, that allows you to modify the value in the map directly, through x = value, or x << arr etc .
if mut x := a.data[key] { should produce a reference
I think V tries to help the programmer transforming sometimes a mut value by a reference, but the problem is the "sometimes". For instance you cannot write fn (mut x &Struct)() { ... } because V says is redundant, but then here results mut wasn't a reference and (I think) the final user gets confused. I found also this problem similar in issue #23166mut array passed to its closure.
Another question is how expensive is the current copy or clone, say []int value were a larger struct, when here we wanted only know if the key already exists.
Describe the issue
I spend some time to realize that by getting a value from a map we get a copy instead a reference. So when we need to do an accumulator it will be fail if we try to update just the copy. Seems documentation is not clear about this:
I went to the docs to check how to detect a missing key but it doesn't say that the value found is a copy. The same happens using
if/else
oror { }
forms. Next program show the difference:Produces
Links
https://docs.vlang.io/v-types.html#maps
Note
You can use the 👍 reaction to increase the issue's priority for developers.
Please note that only the 👍 reaction to the issue itself counts as a vote.
Other reactions and those to comments will not be taken into account.
The text was updated successfully, but these errors were encountered: