Hacker News new | past | comments | ask | show | jobs | submit login

> How do you decrement an atomic in Go?

Ooh. How do you delete from a slice in Go? With append() of course!

http://stackoverflow.com/questions/25025409/delete-element-i...




That solution (append(a[:0], a[1:]...)) doesn't look remotely performant. I don't have a copy of go handy to test, but exploding most of the list into individual arguments and passing them to a variadic function, just to pack them all back into an array, seems quite circuitous to me.

Is that really the _best_ way to delete from a slice in Go?


> Is that really the _best_ way to delete from a slice in Go?

Yep[0], and it needs a special case to remove the last element of the slice (if the index is user-provided). If you don't care about the slice order you can also swap the element you want to delete with the last element of the slice and shrink the slice by one element. Also fun, it can leak memory.

[0] https://github.com/golang/go/wiki/SliceTricks


That article is a concession speech on why generics are useful. Every single "trick" in the article is titled with the name of the equivalent method in more powerful languages. I don't think its possible to look at that list of tricks or the amount of boiler plate to get simple methods like `sort` or `keys` and assert the language is "simple" and better off for it.


Not even that, Go does have generics for its special magical builtin types (map, slice, channels, … are generic) or functions (close, delete or the aforementioned append are generic)


It doesn't explode the slice:

If the final argument is assignable to a slice type []T, it may be passed unchanged as the value for a ...T parameter if the argument is followed by .... In this case no new slice is created.

https://golang.org/ref/spec#Passing_arguments_to_..._paramet...

(Otherwise, I completely agree that having to use append to remove an element is stupid.)


Unfortunately yes. It's a great example of the sort of thing that Go does pretty badly in my experience – even though it's idiomatic, and technically performant behind the scenes, it looks immediately confusing and slow.


A slice is a view over a continguous array. deleting an index in a continguous array is inherently O(n). Go doesn't obscure this. The pain of writing it out reflects the complexity of the operation.


>The pain of writing it out reflects the complexity of the operation.

And why would one even remotely want that?

Unless they seriously think that if the syntax is painful, people will avoid doing it and get better performance...


It's because it's the wrong data-structure for the job. A slice is not sparse.

If you need to delete from the middle of an ordered collection of items then it's better to use a linked or doubly-linked list (unless it's small then it doesn't matter).


> It's because it's the wrong data-structure for the job. A slice is not sparse.

So?

> If you need to delete from the middle of an ordered collection of items then it's better to use a linked or doubly-linked list (unless it's small then it doesn't matter).

Meh. Deleting from the middle of an array is one memmove, you don't get 1~2 pointers memory overhead, caches blown and having to deref' n pointers getting to the item to remove in the first place. If your language provides arrays, there are almost no cases where you should reach for linked lists without having seriously benched both cases.

And that's before the consideration that a Go linked list means loss of type safety or a hand-rolled hand-specialized implementation.


You don't want to memmove an array which content is shared by another array, which is what slices are about.


If the order of the elements in a slice does not matter, this should be the easiest solution for deleting the element "n":

slice[n] = slice[len(slice)-1]

slice = slice[:len(slice)-1]

Probably one should campaign for adding a delete operator to slices, though so far I have never missed it.


This is a great example of the sort of thing that frustrates me when I'm using Go. Deleting an element from a slice is an obvious, common, simple operation. In order to do this, I have to build that operation from primitives, despite the fact that it will be more error-prone to do so. There are lots of other annoyances like this, too.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: