preslavrachev / preslav.me-comments

0 stars 0 forks source link

2023/02/06/golang-do-we-need-struct-pointers-everywhere/ #16

Open utterances-bot opened 1 year ago

utterances-bot commented 1 year ago

User or *User - Do We Need Struct Pointers Everywhere? · Preslav Rachev

I am a software engineer with a decade-long experience developing software using Java, Go, and Elixir.

https://preslav.me/2023/02/06/golang-do-we-need-struct-pointers-everywhere/

shogg commented 1 year ago

Coming from Java, I now like programming in Go. The lack of a struct value type in Java is what threw me off. C# got records some when, but it seems more of a dirty hack. I don't know if Java have them now. I've read some Java proposals decades ago about user-defined value types, no idea if they got accepted, but they were also very hackish.

The advantage of a value over a pointer is not only the stack. In arrays, you should prefer values to pointers, if feasible. Values benefit from CPU caches, pointers don't. Pointers are an indirection, get the address from the cache, then access the memory address to get the value.

The biggest flaw of Java, IMHO is, the seldom use of arrays. List-Implementations are preferred. And these lists only accept boxed types. Everything must be an Object. Objects are more expensive than pointers, computation and memorywise.

Go got it right: values and pointers don't store metadata, as Java objects do in their headers. A Go value is just the data, a Go pointer is just the address. And still you're able to use reflection in Go. Hint: the metadata is stored in the definitions of variables, not in the types or values.

neoramos commented 1 year ago

Hello Preslav,

First, thank you for this great post.

I came across a similar situation in a project I joined. I started by adding a struct with all fields as values, as I had read that values were the prefer way in GO.

The service already had code to validate the content of each field within the struct. The problem I ran into was with numeric values. I could protect from empty values in strings with x != "", etc. However, the empty value of integers could not be checked with a y != 0, as 0 could be a valid value. I ended up adding the integer fields as pointers (*int), just to be able to validate them.

Do you have any advice on how to avoid pointers for numeric struct fields such as the one I described?

Again, thank you. Neo

lesichkovm commented 1 year ago

@neoramos yep I totally agree with your intutition that a pointer is the wrong solution. According to me a pointer is an indicator of a code smell. We tend to quickly jump to to it as its the easiest work around, and we do not spend the time to properly structure our types.

shogg commented 1 year ago

Yep, introducing pointers for the reason to mark absence of value should be avoided. Most of the time there are other ways to determine it, but you have to think about it. Go has sql.NullString and Co. But this might also have to do with Go shortcomings.