-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
This a minor documentation proposal.
I've witnessed many variations of these two incorrect idioms:
slices.Delete(s, i, i+1)
u := slices.Delete(t, i, i+1)
// keep using t and u...
- In the first one, the caller is ignoring the returned value, because they assume Delete works in-place.
- In the second one, the caller is assigning the returned value to a different variable, because they assume Delete creates a new slice.
Delete does operate in-place, but because of the nature of slice headers, it also returns a new slice header. This API is similar to append.
- A mitigation against ignoring the returned slice is a vet warning: cmd/vet: warn when ignoring the return value of slices.Delete and friends #62729.
- Static analysis is however mostly powerless about "the caller is reusing the original slice header".
The documentation for functions Delete, DeleteFunc, Replace are already correct. But depending on how the user understands the words "remove" and "modified", they may still end up using one of the incorrect idioms, relying on the wrong assumption that the API must be either 100% in-place or 100% by copy.
Here is (in bold) my suggested addition to the docs:
func Delete
Delete removes the elements s[i:j] from s, returning the modified slice.
Delete operates in place, which is destructive for the contents of the original slice.
Delete panics if j > len(s) or s[i:j] is not a valid slice of s.
Delete is O(len(s)-i), so if many items must be deleted, it is better to
make a single call deleting them all together than to delete one at a time.
Delete zeroes the elements s[len(s)-(j-i):len(s)].
func DeleteFunc
DeleteFunc removes any elements from s for which del returns true, returning the modified slice.
DeleteFunc operates in place, which is destructive for the contents of the original slice.
DeleteFunc zeroes the elements between the new length and the original length.
func Replace
Replace replaces the elements s[i:j] by the given v, and returns the
modified slice.
Replace operates in place, which is destructive for the contents of the original slice.
Replace panics if j > len(s) or s[i:j] is not a valid slice of s.
When len(v) < (j-i), Replace zeroes the elements between the new length and the original length.