--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/f53377a0-ddc1-4842-ac7a-a796d85b7077n%40googlegroups.com.
Go likes you to test explicitly for failure where that is possible: did the open fail, did the pipe break, etc.Multiple return values make this clear by avoiding the need for a "reserved" error value of the normal-case return.Go likes untested actions to work. In your case adding an existing key to a map replaces the old entry, accessing a missing entry returns the default value. ["no surprises"]Go likes you to combine these approaches to make your own more elaborate behaviors using the "comma OK" approach that Axel shared. In your case, adding, and deleting could complain if there is already a matching entry, or not a matching entry, or -- and this is the real reason -- by looking at the payload of a new or matching entry to use application logic to decide if that's ok or not. Only you can know so Go won't second guess you, and the test-rather-than-panic style is because testing right there is deemed the right way.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEc5MO-FS1esLDJGoKRUq0tneJ5v6GR5T8JQMDFgjx9pQ%40mail.gmail.com.
Joe, your question is perfectly answered by Axel.I'll just share a few (personal) Go "style" comments:Go likes you to test explicitly for failure where that is possible: did the open fail, did the pipe break, etc.Multiple return values make this clear by avoiding the need for a "reserved" error value of the normal-case return.Go likes untested actions to work. In your case adding an existing key to a map replaces the old entry, accessing a missing entry returns the default value. ["no surprises"]Go likes you to combine these approaches to make your own more elaborate behaviors using the "comma OK" approach that Axel shared. In your case, adding, and deleting could complain if there is already a matching entry, or not a matching entry, or -- and this is the real reason -- by looking at the payload of a new or matching entry to use application logic to decide if that's ok or not. Only you can know so Go won't second guess you, and the test-rather-than-panic style is because testing right there is deemed the right way.On Thu, Aug 13, 2020 at 11:42 AM 'Axel Wagner' via golang-nuts <golan...@googlegroups.com> wrote:
No, there isn't, but you can check if the value exists:x, ok := m[k]if !ok {panic("does not exist")}You can also wrap that with methods, if you want to avoid the extra check.I disagree with you that panicking on a non-existent key is better - either in general, or in the majority of cases. Personally, I don't think I encountered many use-cases where the zero-value wasn't the perfect thing to use. I'm not saying your use-case doesn't exist or even that it's rare, just that I don't think you can generalize from your experience here.
On Thu, Aug 13, 2020 at 8:36 PM Joe Marty <joe....@smartersorting.com> wrote:
I'm very new to Go - apologies in advance if I'm missing something:I find it frustrating that there's no way to create a map that does *not* automatically return a zero value for undefined key access by default.I love the fact that Go doesn't return "nil" for this use case (I love Ruby, but I don't think they got that quite right), but returning a default value is worse! It would make so much more sense if it would just panic when accessing an undefined key. I'm not a Python guy, but I think this is something Python got right.Creating a map that returns some default value when you access an undefined key should be a special kind of map, or a special argument to initializing the map (which Ruby does allow). In Go, is there even any way to create a map that panics when you access an undefined key?-Joe
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/f53377a0-ddc1-4842-ac7a-a796d85b7077n%40googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEc5MO-FS1esLDJGoKRUq0tneJ5v6GR5T8JQMDFgjx9pQ%40mail.gmail.com.--Michael T. Jones
michae...@gmail.com
Yeah, I can see how the convention of "always testing for failure" is better than a panic, in that it requires you to handle the possibility of a failure for things that may commonly fail. In that respect though, I don't understand why the "comma OK" is optional.
Elm, for instance, handles things similarly, and has no panics or errors at all as a result because it enforces handling of every possible outcome. But in Go, it seems like... in places where it's not easy to use "comma OK" (maybe in the middle of a larger expression), or if I forget, I could easily confuse the default result from a boolean map (false) with an actual false value!
In Python or Elm, or Ruby, there would be a clear distinction and/or a panic.
I agree that it's not a common case that you might want a panic - in fact I *never* want a panic, haha! I suppose it's more of a question of language convention vs. language enforcement. Because I'm human, and rarely write perfect code, I would prefer for the compiler (or the runtime environment) to have an error if I make a mistake like that.
I suppose maybe there's a way to setup a style linter to enforce a failure check for every map access? (But that's a lot more tedious than just enabling a default where appropriate, or disabling it where it's not...)
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/3be33769-aa34-491d-af25-dbfe362807c5n%40googlegroups.com.
If I know that a value exists, or am fine using the zero value (again, that's the majority of my personal use-cases for maps at least), having to use a statement just to discard the extra bool is annoying.
FWIW, using `map[K]bool` as a set is a great example for where this behavior is super convenient. Far more convenient than if you use `map[K]struct{}`, which has significant syntactical overhead.
Well, an exception-based language of course is less hesitant to throw exceptions. But as a result, they often get ignored and cause crashes with useless stack traces (useless to the user, that is - the developer might find them more useful, but as a user, I want to know what I did wrong *without* having to look at source code).
I suppose maybe there's a way to setup a style linter to enforce a failure check for every map access? (But that's a lot more tedious than just enabling a default where appropriate, or disabling it where it's not...)It's something you could do for your code base, for sure. But personally, I'd consider doing that bad style. Only check for membership, if membership is actually important.
If I know that a value exists, or am fine using the zero value (again, that's the majority of my personal use-cases for maps at least), having to use a statement just to discard the extra bool is annoying.Right, so this brings me back to a nice solution to both our use cases, which would be to initialize the map as either having a default or not having a default. You don't have to check for failure, I don't have to worry about forgetting to check for failure... right? :D
FWIW, using `map[K]bool` as a set is a great example for where this behavior is super convenient. Far more convenient than if you use `map[K]struct{}`, which has significant syntactical overhead.Sure, that's a bad alternative. So again, back to my original theory, seems like an overall better option to have `map[K]bool(false)` if you want the default to be false vs `map[K]bool` if you don't. Or perhaps `openMap[K]bool` if you want every key to return something vs `closedMap[K]bool` if you don't.Well, an exception-based language of course is less hesitant to throw exceptions. But as a result, they often get ignored and cause crashes with useless stack traces (useless to the user, that is - the developer might find them more useful, but as a user, I want to know what I did wrong *without* having to look at source code).Fair point :)I suppose maybe there's a way to setup a style linter to enforce a failure check for every map access? (But that's a lot more tedious than just enabling a default where appropriate, or disabling it where it's not...)It's something you could do for your code base, for sure. But personally, I'd consider doing that bad style. Only check for membership, if membership is actually important.Well I definitely agree there about the ideal state - I should only have to check for membership when membership is important ideally. So wouldn't it also be ideal to allow the developer to indicate when membership is important vs when it's not upon initialization, so that the runtime can panic when panic is appropriate, and just move along when "there's nothing to see here" - all without requiring any convention or ongoing discernment from maintainers of a code-base?(And maybe not even panic, but just require checking for failure in one case, but not in the other, so that mistakes can be caught at compile time!) :D
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/e2636a6e-8478-44eb-bc44-e0b0a8d3b5cbn%40googlegroups.com.
If I know that a value exists, or am fine using the zero value (again, that's the majority of my personal use-cases for maps at least), having to use a statement just to discard the extra bool is annoying.Right, so this brings me back to a nice solution to both our use cases, which would be to initialize the map as either having a default or not having a default. You don't have to check for failure, I don't have to worry about forgetting to check for failure... right? :D