Live data from Hacker News

Be careful with Go struct embedding

mattjhall.co.uk

51–60 of 101 posts

Re: Be careful with Go struct embedding

#51
post #34

My personal conspiracy is that Golang is an epic prank. Make a language that's really good in some ways and just horrible in other ways for no reason whatsoever. So that when it's critics point out contradictory features like embedding, it's defenders can be the ultimate troll and say things like "but, actually, it's a simple language because it doesn't have while loops". It's the best explanation I have for some of…

> just horrible in other ways for no reason whatsoever

I bet the reasons were very mundane: initial project scope, deadlines, performance review cycle. "This simplest thing that could possibly work", etc.

Re: Be careful with Go struct embedding

#52
Who's actually expecting `xyz.com` here?

Spec: https://go.dev/ref/spec#Selectors > x.f resolves to the field/method at the shallowest depth in T. If there isn’t exactly one at that depth, it’s illegal.

Embedding promotes fields; on name collisions the shallowest wins. So `opts.URL` is `FooService.URL` (depth 1), not `BarConnectionOptions.URL` (depth 2).

Re: Be careful with Go struct embedding

#53
post #45

Am I the only one who found the described behavior to be intuitively correct? I did expect it to print "abc.com".

This may be intuitively correct, but to my mind it is architecturally wrong. A good language should not tolerate ambiguity and offer to guess which behavior is correct.

Why is it ambiguous though? The second URL is nested

Are thy not accessed like

opts.URL == abc.com

and

opts.BarConnectionOptions.URL == xyz.com

what leads you think otherwise?

Re: Be careful with Go struct embedding

#54
post #34

My personal conspiracy is that Golang is an epic prank. Make a language that's really good in some ways and just horrible in other ways for no reason whatsoever. So that when it's critics point out contradictory features like embedding, it's defenders can be the ultimate troll and say things like "but, actually, it's a simple language because it doesn't have while loops". It's the best explanation I have for some of…

Is it possible that it's like every other language, with flaws and tradeoffs that don't always make sense to everyone? Why make it more complicated than that?

This might sound bad, but having worked in a few different languages, I find it kind of cute how some parts of Go seem to promote simplicity while others are simply what the authors were used to growing up. Sometimes it frustrates me when I write Go, when I see a tradeoff due to the latter. But yeah. Languages tend to have a lot of subjectivity of their author in them. The more "strict" the language is, the more confined you are to the author's opinions.

Re: Be careful with Go struct embedding

#55
post #32

I like the Go language because it's straightforward and clear, even if it looks a bit plain. I hope the feature mentioned in the article will cause a compiler error. However, I wouldn't use this approach when writing my own code.

> I hope the feature mentioned in the article will cause a compiler error. Read the article. It won't. At best you can perhaps find a linter that'll report it? > However, I wouldn't use this approach when writing my own code. You might use it by accident.

I know, so this is a wish. Looking at other comment sections, there are actually linters that can warn about such behavior.

Re: Be careful with Go struct embedding

#56

Over the course of ~10 years of writing Go, my ratio of "embedding a struct" to "regretting embedding a struct" is nearly 1:1. I do not embed structs anymore. It is almost always a mistake. I would confidently place it in the "you should be required to import 'unsafe' to use this feature" bin.

I think there are a handful of cases where it is a nice-to-have and would be sad if it was removed in a hypothetical Go 2. Making a utility wrapper struct that overrides a method or adds new helper methods while keeping the rest of the interface is the most common example, though there are also some JSON spec type examples which are a little more esoteric. However, you need to be mentally prepared to switch to the boilerplate version as soon as things start getting hairy.

But yes, for anything more complicated I have generally regretted trying to embed structs. I think requiring "unsafe" is a bit too strong, but I think the syntax should've been uglier / more in-your-face to discourage its use.

(Fellow 10+ years Go user.)

Re: Be careful with Go struct embedding

#57
I have code that wouldn't work without embedding. Basically, I have a type that annotates any AWS paginate and is capable of streaming all the results as a sequence. It embeds the original client so you get all the functionality of the client, but it also wraps the functions that support a pagination. I can't think of an easier or clearer way to do it.

Re: Be careful with Go struct embedding

#58
post #45

Am I the only one who found the described behavior to be intuitively correct? I did expect it to print "abc.com".

This may be intuitively correct, but to my mind it is architecturally wrong. A good language should not tolerate ambiguity and offer to guess which behavior is correct.

It's not ambiguous though. The behaviour is very clearly defined in the language spec.

https://go.dev/ref/spec#Selectors

As far as language specs go, Go's is really quite concise and I strongly encourage everyone I onboard to spend an afternoon reading it end to end at some point in their first couple weeks.

Re: Be careful with Go struct embedding

#59

Am I the only one who found the described behavior to be intuitively correct? I did expect it to print "abc.com".

I'm confused at the responses saying this intuitive. It's like saying:

  var x string
  x = "abc.com"
  x = "xyz.com"
  fmt.Println(x)
will print abc.com and that's totally expected.

The normal intuition would be that the latter operations or (re)definitions override the preceding ones.

Re: Be careful with Go struct embedding

#60

I like the Go language because it's straightforward and clear, even if it looks a bit plain. I hope the feature mentioned in the article will cause a compiler error. However, I wouldn't use this approach when writing my own code.

This comment unexpectedly received a few downvotes, which might be due to some misunderstanding. My point is as follows: 1. People choose Go for various reasons. 2. Beginners will encounter the issues mentioned in the article, so I hope there could be a feature that provides hints for newcomers. While the compilation errors might not be reasonable, at least the LSP/linter could provide some guidance.
Post reply on HN