Comment by Mawr
16 hours ago
> it lacks iterators -- every time you must write a big cycle instead
It has iterators - https://pkg.go.dev/iter.
> It lacks simple things like check if a key exists in a map.
What? `value, keyExists := myMap[someKey]`
> Try removing an element from an array - you must rely on some magic and awkward syntax, and there's no clear explanation what actually happens under the hood (all docs just show you that a slice is a pointer to a piece of vector).
First of all, if you're removing elements from the middle of an array, you're using the wrong data structure 99% of the time. If you're doing that in a loop, you're hitting degenerate performance.
Second, https://pkg.go.dev/slices#Delete
> `value, keyExists := myMap[someKey]`
If I don't need the value, I have to do awkward tricks with this construct. like `if _, key_exists := my_may[key]; key_exists { ... }`.
Also, you can do `value := myMap[someKey]`, and it will just return a value or nil.
Also, if the map has arrays as elements, it will magically create one, like Python's defaultdict.
This construct (assigning from map subscript) is pure magic, despite all the claims, that there's none in Golang.
...And also: I guess the idea was to make the language minimal and easy to learn, hence primitives have no methods on them. But... after all OOP in limited form is there in Golang, exactly like in Rust. And I don't see the point why custom structs do have methods, and it's easier to use, but basic ones don't, and you have to go import packages.
Not that it's wrong. But it's not easier at all, and learning curve just moves to another place.
> Also, if the map has arrays as elements, it will magically create one, like Python's defaultdict.
Err, no Go doesn't do that. No insertion happens unless you explicitly assign to the key.
You're right. But it will return something: https://go.dev/play/p/Cz6aeGpURgo
prints `map[123:[456]]`
I guess it's convenient compared to Rust's strict approach with entry API. But also, what I found is that golang's subscript returns nil in one case: if the value type is a nested map.
output:
2 replies →
> Also, you can do `value := myMap[someKey]`, and it will just return a value or nil.
It might if your map is a `map[typeA]*typeB` but it definitely won't return a `nil` if your map is anything like `map[typeA]typeC` (where `typeC` is non-nillable; i.e. int, float, string, bool, rune, byte, time.Time, etc.) - you'll get a compile error: "mismatched types typeC and untyped nil".
_ is idiomatic and not an awkward trick. It keeps signatures consistent even when you don't need the value.
> But it's not easier at all, and learning curve just moves to another place.
Hard disagree. Go has its sharp corners, but they don’t even approach the complexity of the borrow checker of Rust alone, let alone all of the other complexity of the Rust ecosystem.