TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Go Enums Suck

137 pointsby pionarabout 1 year ago

30 comments

015aabout 1 year ago
`iota` is maybe the only language feature of Go that I would actually support removing. Obviously, they never will because it would be a breaking change. Its just so vestigial. There&#x27;s literally no reason to use it, and a very big reason why you shouldn&#x27;t: The encoded value can change any time you re-compile your program, so you can&#x27;t <i>actually</i> use it for anything where the value of the enum leaves the process that instantiated it (e.g. marshaling to JSON and sending over the wire). That&#x27;s a terribly poor characteristic for a feature in a &quot;systems&quot; (emphasis on plural) programming language to have, one would think.
评论 #39567643 未加载
评论 #39572810 未加载
评论 #39573918 未加载
ilove_banh_miabout 1 year ago
Ada has excellent enumeration types, and subtypes, and compile-time checking of case statement coverage for enum values, and an optional representation mechanism to control the binary value for each (symbolic) enum value. I&#x27;m not aware of any other language with that kind of enum type system.<p>See e.g. <a href="https:&#x2F;&#x2F;adaic.org&#x2F;resources&#x2F;add_content&#x2F;docs&#x2F;craft&#x2F;html&#x2F;ch05.htm#5.9" rel="nofollow">https:&#x2F;&#x2F;adaic.org&#x2F;resources&#x2F;add_content&#x2F;docs&#x2F;craft&#x2F;html&#x2F;ch05...</a>
评论 #39568717 未加载
评论 #39566837 未加载
评论 #39568962 未加载
marklar423about 1 year ago
If you&#x27;re using protobufs anyway, you can get also get this functionality generated by using a proto enum: <a href="https:&#x2F;&#x2F;protobuf.dev&#x2F;reference&#x2F;go&#x2F;go-generated&#x2F;#enum" rel="nofollow">https:&#x2F;&#x2F;protobuf.dev&#x2F;reference&#x2F;go&#x2F;go-generated&#x2F;#enum</a>. It works really nicely and has all the features mentioned in the article.<p>One added benefit is it serializes&#x2F;deserializes safely (even when you add &#x2F; remove values), so you can persist and read back values without a problem - even to a different language.
taericabout 1 year ago
A thing that so many enum solutions miss is that you have to have a path for a value outside of the current definition, or you lose a lot of flexibility in compatibility with any data that crosses wires or disks. Sounds fine for a lot of cases, of course, but in a world of mixed deployment fleets working on data, you pretty much have to have a way to allow a value that is not part of your current definition, or you are basically placing a &quot;poison pill&quot; on your system.
评论 #39565227 未加载
评论 #39565617 未加载
the__alchemistabout 1 year ago
Go and Python have OK enums. I will use them, but they could be simpler&#x2F;more expressive. This begs the question: Is there an obstacle to releasing better enums in the next Python and Go versions? If the concern is about breaking backwards compatibility, I would be OK with a new type. Is it a culture issue, ie that Python and Go programmers don&#x27;t use enums much? (Chick + egg here)<p>Rust&#x27;s enums are great. No &quot;auto&quot; boilerplate if not mapping to an integer, exhaustive pattern-matching, sub-types etc.
评论 #39565092 未加载
评论 #39570032 未加载
RamblingCTOabout 1 year ago
If people are spending this much time circumventing your language design, you oughta take a look inside. Go &quot;enums&quot; suck and limit the language.
BugsJustFindMeabout 1 year ago
&gt; <i>Go doesn’t technially have Enums and it is a missing feature in my book but there is a Go idiomatic way to achieve roughly the same thing.</i><p>Oh, so it&#x27;s a lot like Python then.<p>&gt; <i>This is fine however it is nothing but an integer under the covers this means what we actually have is:</i><p>Oh, so it&#x27;s a lot like C++ then.<p>&gt; <i>But what you notice here is we have no string representation of these Enums so we have to build that out next</i><p>Have to!<p>Yes this still all sucks. (But at least there&#x27;s ugly historical precedent!)
评论 #39565663 未加载
评论 #39565113 未加载
评论 #39565371 未加载
llmblockchainabout 1 year ago
It&#x27;s kind of strange to see them complain about enums and then promote a DSL-specific tool they made for generating enums.<p>At the same time, Go has generators built in and can generate enum tables, enum to strings, and other things they have shown. I am unsure why they didn&#x27;t do it the &quot;Go&quot; way.
评论 #39566483 未加载
评论 #39565750 未加载
beautronabout 1 year ago
I love Go&#x27;s lightweight, somewhat implicit style of doing enums.<p>You just declare an int type, and then a list of constants of that type.<p>People are complaining about &#x27;iota&#x27; here, but I think it&#x27;s slick and great. It combines so nicely with eliding types and values from subsequent const declarations:<p><pre><code> type MyEnum int const ( Value1 MyEnum = iota Value2 Value3 ... ) </code></pre> Nice and simple. Most of the syntax is just the enum value identifiers. And it works well for bit flags too:<p><pre><code> type MyFlags int const ( Flag1 MyFlags = 1 &lt;&lt; iota Flag2 Flag3 ... ) </code></pre> Most of the above syntax isn&#x27;t specific to enums (so you&#x27;re already getting a lot of other things from it). The only enum-specific syntax is iota and the eliding type&#x2F;value rule.<p>People seem to want their languages to have all sorts of guardrails, but I find many of these cumbersome. Go gives me the one enum guardrail I care about: The enums are different types, so I can&#x27;t use a MyEnum as a MyFlag, or vice versa.<p>I&#x27;ve worked on giant Go codebases, with Go-style enums all over the place, and the lack of compiler-enforced exhaustive enum switches just hasn&#x27;t been a problem. And it&#x27;s nice to be able to use non-exhaustive switches, when you want them. Go is simple and flexible here.<p>The article criticizes Go incorrectly with statements such as these:<p>&gt; This also means any function that uses these or a struct that contains these can also just take an int value.<p>&gt; Anywhere that accepts an Operation Enum type will just as happily accept an int.<p>This is just not true. Here&#x27;s an example you can run: <a href="https:&#x2F;&#x2F;go.dev&#x2F;play&#x2F;p&#x2F;8VGufuxgK6b" rel="nofollow">https:&#x2F;&#x2F;go.dev&#x2F;play&#x2F;p&#x2F;8VGufuxgK6b</a><p>The above example tries to assign an int variable to a MyEnum variable, and gives the following error: &quot;cannot use myInt (variable of type int) as MyEnum value in variable declaration&quot;<p>This error directly contradicts what is claimed in the article. Perhaps they mean that MyEnum will accept an integer literal, in which case I would argue that a guardrail here is silly, because again the problem just doesn&#x27;t really come up in practice. Regardless, the author is not being very precise or clear in their thinking.
kevmo314about 1 year ago
&gt; Anywhere that accepts an Operation Enum type will just as happily accept an int. This is a real pain as it almost completely negates the work we have done here.<p>Is this a real problem? If there&#x27;s a function signature that accepts `Operation`, the caller must explicitly cast the `int` to `Operation`. At that point, it&#x27;s the caller&#x27;s own fault.<p>So I&#x27;m not really following what this is solving. As demonstrated in the article, sometimes you want string constants, sometimes you want `iota`, other times you want `1 &lt;&lt; iota`. I like that Go doesn&#x27;t dictate which I have to use if I declare an &quot;enum&quot;.
评论 #39565640 未加载
zoogenyabout 1 year ago
I have a totally tangential ramble queued up on this topic.<p>I like philosophy and I read it as a total amateur. <i>Naming</i> is a big topic in modern philosophy [1] with a huge amount of depth. I think of it in terms of my naïve understanding of Wittgenstein&#x27;s later work and the idea that the meaning of a word actually comes from its usage within the context of a set of collaborating agents.<p>If I say to a programmer &quot;use a vector&quot;, that will mean something specific if we are writing C++ and I want to use a resizable array. And it could mean something totally different in the context of a 3d rendering engine.<p>I think of how often I see words like &quot;Context&quot;, &quot;Session&quot;, &quot;Kernel&quot; and all of their myriad uses.<p>So I see articles like this as just a pointless argument because we are crossing some boundary between distinct language games. The author of this article thinks &quot;Enum&quot; means one thing. But it is actually the case that &quot;Enum&quot; is unspecified outside of some particular context. And in this case, the author is bringing some outside context and trying to reuse it inappropriately.<p>1. <a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Naming_and_Necessity" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Naming_and_Necessity</a>
评论 #39567809 未加载
评论 #39566813 未加载
评论 #39565731 未加载
评论 #39565696 未加载
mathiasgredalabout 1 year ago
If you are already using gRPC in your codebase, then you can define your enums with Protobuf, which does much of the same as the tool shown in this article.
评论 #39569507 未加载
t0astbreadabout 1 year ago
What I like about Go is not the language itself (I&#x27;m not a language designer but I dislike a lot of choices that Go makes) but the entire culture around it of doing things the idiomatic way and moving on. I&#x27;m someone who, if you give them a tool that&#x27;s flexible, will spend time optimizing it. And I&#x27;m already busy optimizing other stuff so it&#x27;s nice to have something constant to build upon.<p>Oh and you don&#x27;t <i>have to</i> use large power-hungry IDEs that don&#x27;t integrate with any sort of config management to get a decent experience! (&#x2F;hj)<p>If I ever learn Haskell it&#x27;s over for y&#x27;all though.<p>(Agree with OP btw, using codegen to get the enums I want is a workable remedy for Go&#x27;s lack of enums.)
kletonabout 1 year ago
I use this one <a href="https:&#x2F;&#x2F;github.com&#x2F;abice&#x2F;go-enum">https:&#x2F;&#x2F;github.com&#x2F;abice&#x2F;go-enum</a>
评论 #39567441 未加载
coldteaabout 1 year ago
Go&#x27;s iota is probably one of the worst ideas in all programming languages.<p>Not a full typesafe enum type, the same clunky &quot;enums&quot; (assigned constants) available in C, but they bother to implement an auto-incremented counter.<p>So you can&#x27;t depend on the enum for exhaustiveness warnings e.g. on switch statements, type checking, or correctness, but you do get a useless numeric association autogenerated with iota - so that you can lose the association if you re-order your enum values that you have serialized earlier and want to reload in the future.
评论 #39565319 未加载
评论 #39570348 未加载
评论 #39565650 未加载
评论 #39565337 未加载
skybrianabout 1 year ago
The root cause is wanting to support fixed-size array types in structs, which means nothing can require initialization and everything needs a zero value. The caller can just modify every field directly.<p>This is sort of like how network protocols can’t statically guarantee enums are valid either. When sending bits over the wire, you can send any bits you like. There can be “values reserved for future use,” but to deny their use, you need a runtime check.<p>A similar solution works in Go. A runtime check in a constructor function will fix it. The enum’s value would need to be returned as an unexported field in a struct, which is the only way to guarantee that it’s not writable, except by copying it from another valid value.<p>I don’t see a particular reason why Go couldn’t make this easier.
parhamnabout 1 year ago
Anyone writing a compiles to go, go++ yet? There are generators for better enums, sum types, and more. Bring them all together! I&#x27;m only kinda joking.<p>Im also curious now if the Typescript checker was written in a way that it could be adapted to new languages easily.
评论 #39565583 未加载
评论 #39566389 未加载
评论 #39566917 未加载
jurschreuderabout 1 year ago
You should not use these enums with ints++ in security sensitive applications, because they&#x27;re sensitive to rowhammer attacks.<p>Use uint64s with minimal bit overlap.<p>Maybe nice to include in this ultra-advanced enum libray
Scubabear68about 1 year ago
It has always been surprising to me how primitive Go really is, for no really good reason.<p>I understand the evolution of C, it made perfect sense back when it was invented. And the limitations were necessary due to the wide array of architectures and extremely limited computers of the time in every dimension (CPU speed, IO speed, RAM size, disk size, etc).<p>Many of those dimensions have been improved by several orders of magnitude, and both compilers and runtimes can afford to be comprehensive. Yet we get this ham-strung language out of the gate.<p>Very disappointing.
评论 #39565532 未加载
评论 #39565974 未加载
评论 #39565478 未加载
评论 #39565641 未加载
reactordevabout 1 year ago
“Anywhere that accepts an Operation Enum type will just as happily accept an int.”<p>Hey! Just like in C! I digress, I think the issue is that the author comes from another language where enums are a thing. In go, they aren’t. Enums should be types. Types that don’t infer to an int. Use an interface. Be happy.
shayarmaabout 1 year ago
enums are handled poorly in so many language. very confusing.
SamWhitedabout 1 year ago
I generally agree that this is a big problem with Go, so I don&#x27;t want to quibble too much, but the author acknowledges that the language doesn&#x27;t have enums and that they&#x27;re just trying to use this feature like enums (TBF, this is common advise on the internet and a <i>lot</i> of code does this): instead the author should be thinking &quot;how do I solve this problem without enums since they don&#x27;t exist?&quot;<p>I&#x27;d be willing to bet that there&#x27;s just a better way to do whatever the actual real-world example they want to achieve is (this was not entirely clear to me from the examples in the post).<p>Like I said though, that doesn&#x27;t mean that (real) enums wouldn&#x27;t be an even better way to do it than whatever the Go way is for a given problem, so I don&#x27;t want to quibble too much since I think this is one of my biggest day-to-day complaints about Go, but it&#x27;s worth pointing out that the premise can be flawed and that it&#x27;s still a problem in the language, these two things aren&#x27;t completely orthogonal.<p>TL;DR — Instead of pulling in a code generator and another library, it may be good to think of alternate ways to do the same thing without a lot of extra code footprint.
评论 #39565147 未加载
评论 #39565264 未加载
评论 #39565198 未加载
Rapzidabout 1 year ago
Enums suck in a bunch of languages including C#. It has binary compatibility issues that need consideration along with some other gotchas and shortcomings.<p>So much so that much of the dotnet official stuff, ie asp.net, use static classes with string fields instead of enums.<p>Unfortunately that doesn&#x27;t play well with libraries that have enum support like entity framework. PITA.<p>One saving grace is the ability to create extension methods on enums.
divanabout 1 year ago
It&#x27;s actually the coolest thing about Go enums, that they just it – enums.<p>Developers with a background in other languages assume all enums&#x27; use cases need string representation. Well, no. They are needed sometimes, but not always.<p>The same with the ability to pass int to the enum. Author says:<p>&gt; Anywhere that accepts an Operation Enum type will just as happily accept an int.<p>Well, this is simply not true. [1] You&#x27;ll have to cast your int into your enum, which is totally fine if it&#x27;s your intent. Granted, there are plenty of valid cases where you need validated input, especially for the public libraries. But hey, not every code is a publicly facing library, and not all need this validation. Why spend CPU and memory on something that probably won&#x27;t be needed, and that can be implemented with the existing language primitives?<p>In the end, the author did a great job of solving his own requirements around enums and even wrote a code generator that helps him generate this for millions of enum types per second. :)<p>[1] <a href="https:&#x2F;&#x2F;play.golang.com&#x2F;p&#x2F;Ch-IZ26p0v8" rel="nofollow">https:&#x2F;&#x2F;play.golang.com&#x2F;p&#x2F;Ch-IZ26p0v8</a>
评论 #39565953 未加载
pipeline_peakabout 1 year ago
This feature that technically doesn’t exist sucks
sgiftabout 1 year ago
I love Go. Especially how the devs stubbornly refuse to learn anything from Java, but stumble boneheaded into everything that Java solved over the years. Generics? We don&#x27;t need that .. (time goes on) .. okay, damn it. Here! Generics! Enums? We don&#x27;t need that, just do iota&#x2F;integers!<p>How long will it be this time until the Go devs accept that Java Enums are a safer and better abstraction over integers for the cases where you&#x27;d want an Enum? And that they allow something like EnumSet, which are type-safe bitsets, without everyone having to do that by hand?
评论 #39565173 未加载
评论 #39565386 未加载
评论 #39565324 未加载
评论 #39565322 未加载
评论 #39565634 未加载
评论 #39565432 未加载
评论 #39565184 未加载
mseepgoodabout 1 year ago
Go doesn&#x27;t have enums and as such they cannot suck. Something that is non-existent can&#x27;t be good or bad. The title is clickbait. Go has constants, and they have a great feature for defining constants (iota).
评论 #39565140 未加载
评论 #39565345 未加载
评论 #39565329 未加载
mojubaabout 1 year ago
<p><pre><code> func (o Operation) IsValid() bool { if o == Unknown { return false } return true } </code></pre> Why, oh why don&#x27;t people just write<p><pre><code> return o != Unknown </code></pre> This is so common in the code that I&#x27;m seeing on the Internet, on GitHub etc. Is it because people don&#x27;t understand booleans?
评论 #39566123 未加载
评论 #39565951 未加载
评论 #39565842 未加载
评论 #39566425 未加载
评论 #39566306 未加载
评论 #39565834 未加载
评论 #39566461 未加载
pjmlpabout 1 year ago
Pascal in its original 1970&#x27;s design,<p><pre><code> type myEnum = (value1, value2, value3, value4) </code></pre> Naturally that is too advanced and slows compile times.
评论 #39565866 未加载
评论 #39565665 未加载
评论 #39566445 未加载
zer00eyzabout 1 year ago
&gt;&gt;&gt; But what you notice here is we have no string representation of these Enums so we have to build that out next, for this I just use a map[Operation]string and instantiate this with the defined string constants.<p>Cries in I18N...
评论 #39565614 未加载