Closed go-xworkflow closed 3 months ago
V version V 0.4.6 736067d
Environment details (OS name and version, etc.) V full version: V 0.4.6 736067d OS: Manjaro Linux x86_64 Kernel: 6.6.32-1-MANJARO
Appending to the parent array may or may not make it independent from its child slices. The behaviour depends on the parent's capacity and is predictable:
mut a := []int{len: 5, cap: 6, init: 2}
mut b := unsafe { a[1..4] }
a << 3
// no reallocation - fits in `cap`
b[2] = 13 // `a[3]` is modified
a << 4
// a has been reallocated and is now independent from `b` (`cap` was exceeded)
b[1] = 3 // no change in `a`
println(a) // `[2, 2, 2, 13, 2, 3, 4]`
println(b) // `[2, 3, 13]`
The result of running this code:
[2, 2, 2, 2, 2, 3, 4]
[1, 3, 13]
You can call .clone() on the slice, if you do want to have an independent copy right away:
mut a := [0, 1, 2, 3, 4, 5]
mut b := a[2..4].clone()
b[0] = 7 // Note: `b[0]` is NOT referring to `a[2]`, as it would have been, without the .clone()
println(a) // [0, 1, 2, 3, 4, 5]
println(b) // [7, 3]
Code running results
[0, 1, 2, 3, 4, 5]
[7, 3]
However, I ran the following code and got the same result, which confused me and was totally inconsistent with what was described in the documentation.
mut a := [0, 1, 2, 3, 4, 5]
mut b := a[2..4]
b[0] = 7 // Note: `b[0]` is NOT referring to `a[2]`, as it would have been, without the .clone()
println(a) // [0, 1, 2, 3, 4, 5]
println(b) // [7, 3]
Code running results
[0, 1, 2, 3, 4, 5]
[7, 3]
The documented example was done before we changed the default of the compiler to do a clone, and a notice that either an unsafe{}
wrapper, or calling .clone()
is needed to silence the notice.
i.e. the documented behavior in the example, currently needs mut b := unsafe { a[2..4] }
.
I'll update the docs.
Fixed in 0e543fb .
Describe the issue
Array Slices A slice is always created with the smallest possible capacity cap == len (see cap above) no matter what the capacity or length of the parent array is. As a result it is immediately reallocated and copied to another memory location when the size increases thus becoming independent from the parent array (copy on grow). In particular pushing elements to a slice does not alter the parent:
The result of running this code:
Are there any major errors in the V language documentation? The content described in the documentation is seriously inconsistent with the running results. This made me confused when I was learning V language. Please excuse my poor English
Links
https://docs.vlang.io/v-types.html#arrays