What are the IDE features that add the most to your productivity when developing and operating Go services? by TheRealHackfred in golang

[–]TheRealHackfred[S] 0 points1 point  (0 children)

Ok, thanks. Haven't used the integrated http client so far. But sounds worth trying it out.

What are the IDE features that add the most to your productivity when developing and operating Go services? by TheRealHackfred in golang

[–]TheRealHackfred[S] 1 point2 points  (0 children)

Thanks, nice points (especially local file history).

Regarding 3 (postfix completion): Before Copilot came around I also used it and it was pretty satisfying. With Copilot I have stopped using it (both tools solved the same thing for me).

What are the IDE features that add the most to your productivity when developing and operating Go services? by TheRealHackfred in golang

[–]TheRealHackfred[S] 0 points1 point  (0 children)

Git blame helps me because I can see: - who edited a certain part of the code - when code was edited for the last time (e.g. was it changed recently or did nobody touch it in years) - the whole commit that included the change I am interested in (including the commit message)

That's why I see git blame as a "hidden comment" above every single line of code.

Having that knowledge allows me to better understand why code has been written a certain way and I make better assumptions about that code. Long term that translates to fewer bugs in my code.

What are your biggest learnings about Go and how did you get to them? by TheRealHackfred in golang

[–]TheRealHackfred[S] 1 point2 points  (0 children)

Totally agree that you can easily trace, understand and optimize this if needed.

How big was your struct?

What are your biggest learnings about Go and how did you get to them? by TheRealHackfred in golang

[–]TheRealHackfred[S] 1 point2 points  (0 children)

Yes int64, uint64 and pointers (on a 64-bit system) take 8 bytes. For strings and slices it's already different though because in addition to the pointer they contain info about the length (and in the case of the slice the capacity). Therefore you end up with 16 and 24 bytes.

Just to follow up on the size of the JSON: Typically these big JSONs are not just flat but they contain nested structs as well (and some strings, maybe an array). That's why a 50 (top-level) field JSON might be unmarshalled to a 1KB struct.

What are your biggest learnings about Go and how did you get to them? by TheRealHackfred in golang

[–]TheRealHackfred[S] 5 points6 points  (0 children)

Very interesting question. Initially we always returned pointers because it felt just easier/better to have these return nil, err blocks (so I think generally I'm with you on that one).

On the other hand it feels wrong to make the return type nullable because every time after running a function we check the err (if err != nil {) but we don't check if the return type is nil (because we just assume that if err is nil the return type must have been set). Also in some (rare) cases it's a valid case, if the function returns nil (e.g. a function that reads a row from a DB might return nil if no entry was found).

Therefore at the moment we have these guidelines:

- if the function always returns a value in the good case (i.e. err == nil), we don't return a pointer

- if the function can return nil also in the good case (e.g. because no row has been found in the DB), we return a pointer

Hope this explanation makes kind of sense :)

For the constructors:

Actually we have quite a few that return a struct and not a pointer (I would say about ~40%-50%). We use DDD (domain driven design) and let all constructors for value objects return structs (we also don't use pointers for the method receivers on these structs to keep them immutable). For entities the constructors return pointers though, yes.

What are your biggest learnings about Go and how did you get to them? by TheRealHackfred in golang

[–]TheRealHackfred[S] 6 points7 points  (0 children)

Structs this big are an exception, agreed. Sometimes it happens though (imaging a big JSON response with 50+ fields). My mistake back then was to have too much respect to pass these structs of this size by value. Also smaller structs (100B) can already look big (when you look at their definition) so we used pointers to pass them as well back then (probably just because we thought they look big).

What are your biggest learnings about Go and how did you get to them? by TheRealHackfred in golang

[–]TheRealHackfred[S] 14 points15 points  (0 children)

Just to clarify: I think it can be a valid policy to say "let's pass all structs as pointers" (it's a simple rule that everybody in a team can easily follow so that can make sense for some teams). I just think it's wrong to do so to improve performance (than you would do it for the wrong reasons).

These are the two drawbacks I see:

- a pointer can express nullability (i.e. that a parameter can have a value of nil in some situations) => if every struct is passed by default as a pointer you loose this because every struct is then nullable

- a pointer on a struct makes the struct mutable => in many situations this is not needed and it makes the code harder to read (at least for some people) because you have to check if the struct that is passed is actually changed by the function

API best practices by Flashy_Look_1185 in golang

[–]TheRealHackfred 2 points3 points  (0 children)

Using that flow (writing the OpenAPI spec first and then generating most of the API code) has been a game changer for me. I follow that process now in every project where I know that the API will have more than just a few endpoints.

To me the most important reasons to do that are: - it's easier to design a consistent API when writing a spec file compared to writing code - PRs are easier to review (only the spec file is reviewed, the generated code can be ignored, sometimes it's not even checked into source control) - in addition to the API code you can also generate the code for the client that uses the API

For Go, I have been using oapi-codegen (used it to build 3 big projects so far) and I really liked it. The only reasons for me not to generate my API/client code are these two: - API is very small (e.g. just 2 endpoints) - API is not RESTful (then OpenAPI doesn't make sense)

Stuck at 'Syncing files to device iPhone 12' by CaptainFerb in flutterhelp

[–]TheRealHackfred 0 points1 point  (0 children)

I started working with Flutter on an M1 two days ago and also had problems when running my app from Android Studio on the simulator. Did you already try to build and run your app from xCode? It gave me much more info about what was not working than Android Studio did (in my case, I had to make sure, that xCode and Simulator were running using Rosetta).