Hi,

Copying struct directly has its problems. As mentioned before, when your 
struct contains mutexes, maps, arrays, or pointers, you may not want your 
struct to be shallow-copied. You may initially have a simple struct that 
can be shallow-copied and it has then been used all over the place. 
However, later on, you may need to change its implementation. You may want 
to make it concurrent safe (with mutexes), etc. If you use plain struct 
with direct copying, you will break your user codes. If you return 
interface and force the user to use the provided copy method, then you 
shouldn't have any problem with future changes to the data type. From 
theoretical perspective, this is also ideal because as long as the method 
signatures don't change, the users shouldn't be affected by changes in the 
implementation.

In addition, if you use the struct's public fields instead of getter / 
setter, you lose the flexibility to use interface as your method argument. 
Hence, your method will be coupled to your struct.

When you return interface, there is nothing preventing you from accepting a 
only subset of the interface. Your method may accept Stringer, Closer, etc. 
and they still work with the practice of returning interface. Hence, you do 
not have to mock the entire interface. You can mock only the methods that 
you require.

I don't agree with opening up the content of struct. The key idea of 
encapsulation is to minimize the contact surface so that any future change 
will not break your code all over the place. As long as the method 
signature remains the same, the user shouldn't be affected by the changes.  

That being said. I can see cases where returning struct is better, 
especially in a low-level work when you may need to squeeze performance / 
memory usage.

On Friday, March 3, 2017 at 7:09:20 AM UTC+7, Eric Johnson wrote:

> Structs give the caller so many immediate benefits:
>
>    - If there's internal state that clients shouldn't muck around with, 
>    then (a) keep a field private, or (b) keep a field private and make it a 
>    pointer to state (such as mutexes).
>    - Structs can be copied directly.
>    - Set and get don't require more methods
>
> On that basis alone, even for simple structures, code saves at least three 
> methods in an interface (one "set", one "get", and one "Clone"). Less code 
> to maintain all around.
>
> On top of that, when writing test code, mocking out someone's else's API, 
> returning structs results in more maintainable code. Why? If the API 
> returns a structure, then the mock must define an interface that captures 
> precisely what is needed from the structure. Whereas, if an API returns an 
> interface, then the mock implementation may not bother with defining a 
> subset interface, thus writing a much larger mock implementation than 
> needed. Again, less code to maintain.
>
> In the end, Go gives you the power to choose either approach, depending on 
> the situation. From my experience with Go code, the default position to 
> return structures (well, typically pointers to structures) ends up being 
> less code, and easier to understand over time. It also forces the design of 
> libraries to be open about the contents of structures, which usually 
> results in easier to understand APIs.
>
> Eric.
>
>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to