Live data from Hacker News

Go Style

google.github.io

111–120 of 212 posts

Re: Go Style

#111
post #45

> A little copying is better than a little dependency. Go takes this to an extreme, though. Generics helps, but the implementation is so limiting that it doesn't help much. > The general rule of thumb is that the length of a name should be proportional to the size of its scope and inversely proportional to the number of times that it is used within that scope. Some (most) of the go code I've seen where I work suffers…

This is probably because Go doesn't allow function overriding. You can't have `streamFromUrl(foo)` and `streamFromUrl(foo, bar)`, so you end up with `streamFromUrlWithFoo(foo)` and streamFromUrlWithFooAndBar(foo, bar)`.

[deleted]

Re: Go Style

#112

Earlier quoted context omitted.

You can make your own Maybe with generics.

And why isn't this build-in since the beginning like in any other sane language? A language where you need to constantly write wrappers around everything just to get basic functionality is quite a miserable language, imho. That's like C…

> A language where you need to constantly write wrappers around everything just to get basic functionality is quite a miserable language, imho. That's like C…

Which makes complete sense, since Go was designed as Google's C for Dummies.

Re: Go Style

#113

> Go interfaces generally belong in the package that consumes values of the interface type, not a package that implements the interface type. The implementing package should return concrete (usually pointer or struct) types. I like this rule. Most companies violate it everywhere. There are good times to ignore it but I always push for func NewThing To return something other than the interface type. The last Go interv…

Yep - return concrete types, but also make sure you have an assertion along the lines of: var _ IfaceType = &ConcreteType{} Somewhere, else you risk not knowing that a change to ConcreteType broke is implementation of IfaceType in a way that you might not know about until a rare runtime code path is executed.

> Somewhere, else you risk not knowing that a change to ConcreteType broke is implementation of IfaceType in a way that you might not know about until a rare runtime code path is executed.

Why would runtime be involved? Surely if ConcreteType doesn't satisfy the interface anymore then the compiler will catch that at any site where a ConcreteType is being used as / cast to an IfaceType?

Or are you talking about iface->iface side-cast?

Re: Go Style

#114
> If the receiver is a “large” struct or array, a pointer receiver may be more efficient. Passing a struct is equivalent to passing all of its fields or elements as arguments to the method. If that seems too large to pass by value, a pointer is a good choice.

For an app that has medium-sized structs in hot paths, this tradeoff introduces considerable tension into the development flow.

However, there is one takeaway for us devs: Don't count on help from the inlining optimization pass of the compiler to evaporate away calling overhead of structs, neither when passed as the receiver nor as an ordinary arg.

Re: Go Style

#115
post #45

> A little copying is better than a little dependency. Go takes this to an extreme, though. Generics helps, but the implementation is so limiting that it doesn't help much. > The general rule of thumb is that the length of a name should be proportional to the size of its scope and inversely proportional to the number of times that it is used within that scope. Some (most) of the go code I've seen where I work suffers…

This is probably because Go doesn't allow function overriding. You can't have `streamFromUrl(foo)` and `streamFromUrl(foo, bar)`, so you end up with `streamFromUrlWithFoo(foo)` and streamFromUrlWithFooAndBar(foo, bar)`.

Consider variadic arguments for such cases.

Re: Go Style

#116
post #107
post #64

Earlier quoted context omitted.

You're assuming that the code was written exception safely. E.g. mu.Lock() foo := bar[baz] // Go is sold as a language without exceptions, so people don't write exception-safe code. Which is fine, except when exceptions are actually caught.

That wouldn't pass a code review where I work... Use a defer to do the unlock

Does defer get called on panic? I thought panic cancels all further execution

Re: Go Style

#117
post #8

I found this "best practice" curious to read: > The standard net/http server violates this advice and recovers panics from request handlers. Consensus among experienced Go engineers is that this was a historical mistake. If you sample server logs from application servers in other languages, it is common to find large stacktraces that are left unhandled. Avoid this pitfall in your servers. I don't think I've ever seen…

> Is this another case of Google forgetting that people use Go outside of Google, or am I reading too much into this?

Whether or not they are forgetting aside, this is Google’s style guide for code bases in Google. I don’t think non-Google Go programmers were a consideration for them.

On a broader note, it seems as though anytime Google publishes something people interpret it as “industry standard” (see their C++ style guide) and apply it to their non-Google projects. I personally don’t see this as healthy.

Re: Go Style

#118
post #8

I found this "best practice" curious to read: > The standard net/http server violates this advice and recovers panics from request handlers. Consensus among experienced Go engineers is that this was a historical mistake. If you sample server logs from application servers in other languages, it is common to find large stacktraces that are left unhandled. Avoid this pitfall in your servers. I don't think I've ever seen…

[deleted]

Re: Go Style

#119

In my opinion the hardest style rules to accept when trying to use this guide are: 1. Do not create "assertion libraries" like `assertEqual(x, y)` [1] 2. Leave testing to the Test function [2] 3. Intialisms (HTTPURL, IOS, gRPC) [3] 4. Function formatting [4] For the record I'm not saying I disagree with these. I just think that folks coming from other languages have a lot of built in muscle memory to do it other ways…

I've read the assertions section a few times and I still don't understand the argument. How is:

  if got == nil {
    t.Errorf("blog post was nil, want not-nil")
  }
Better than

  assert.NotNil(t, got, "blog post")
? They seem to suggest that you lose context, but their "Good" examples are similarly devoid of context.

Re: Go Style

#120

> Go interfaces generally belong in the package that consumes values of the interface type, not a package that implements the interface type. The implementing package should return concrete (usually pointer or struct) types. I like this rule. Most companies violate it everywhere. There are good times to ignore it but I always push for func NewThing To return something other than the interface type. The last Go interv…

That rule is not without its issues when pointers get involved, due to the typed nil problem.

Yeah, this is a setup for hard to understand bugs unless you have a corresponding rule (imposed by a linter) that a concrete type cannot be cast into an interface and then checked against nil (mostly this means when returning a concrete type from a function it should be assigned to a freshly declared variable rather than re-using a variable that could already have an interface type.
Post reply on HN