Background: when I am writing code mostly I end up with some clunky 
solutions I am not happy with and one of the reasons I think is that I 
might be mixing funcs vs methods.

So the question is basically the title.

I have searched both in this group ( without a luck )  and in the Internet 
for possible ideas/answers and I end up with following points:

1. Structs are for representing things, they are things
2. Funcs are for performing actions, calculating things
3. Methods for performing actions on thing state
4. Methods to satisfy interface

Based on these points, let's have a "thing":

```
type Person struct {
   weight float32 // pounds
   height float32 // inches
}
```

And calculate BMI:

```
func CalculateBMI(weight float32 height float32) float32 {
 return weight / (height * height) x 703
}

p := Person{157, 66}

CalculateBMI(p.weight, p.height)
```

However if I would want for example to implement some kind of interface I 
would be forced to use method over func, but it looks weird to me for some 
reason:

```
interface BMICalculator {
    CalculateBMI() float32
}

// Satisfies BMICalculator
func (p * Person) CalculateBMI() float32 {
 return p.weight / (p.height * p.height) x 703
}
```

For example when looking at this STD code I am not longer to reason about 
choices funcs vs methods based on points 
above: 
https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;l=26;drc=8a56c7742d96c8ef8e8dcecaf3d1c0e9f022f708

Why `(a 
<https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=8a56c7742d96c8ef8e8dcecaf3d1c0e9f022f708;bpv=1;bpt=1;l=26?gsn=a&gs=kythe%3A%2F%2Fgo.googlesource.com%2Fgo%3Flang%3Dgo%3Fpath%3Dnet%23param%2520TCPAddr.family%253Aa>
 *TCPAddr 
<https://cs.opensource.google/go/go/+/master:src/net/tcpsock.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=21>
) family 
<https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=8a56c7742d96c8ef8e8dcecaf3d1c0e9f022f708;bpv=1;bpt=1;l=26?gsn=family&gs=kythe%3A%2F%2Fgo.googlesource.com%2Fgo%3Flang%3Dgo%3Fpath%3Dnet%23method%2520TCPAddr.family>()`
 
is implemented as a method when it can be implemented as pure func like:

``` 
func Family 
<https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=8a56c7742d96c8ef8e8dcecaf3d1c0e9f022f708;bpv=1;bpt=1;l=26?gsn=family&gs=kythe%3A%2F%2Fgo.googlesource.com%2Fgo%3Flang%3Dgo%3Fpath%3Dnet%23method%2520TCPAddr.family>
(a 
<https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=8a56c7742d96c8ef8e8dcecaf3d1c0e9f022f708;bpv=1;bpt=1;l=26?gsn=a&gs=kythe%3A%2F%2Fgo.googlesource.com%2Fgo%3Flang%3Dgo%3Fpath%3Dnet%23param%2520TCPAddr.family%253Aa>
 *TCPAddr 
<https://cs.opensource.google/go/go/+/master:src/net/tcpsock.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=21>)
 
int 
<https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=8a56c7742d96c8ef8e8dcecaf3d1c0e9f022f708;bpv=1;bpt=1;l=26?gsn=int&gs=kythe%3A%2F%2Fgo.googlesource.com%2Fgo%3Flang%3Dgo%23int%2523builtin>
 
{
   if a 
<https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=26>
 
== nil || len(a 
<https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=26>
.IP 
<https://cs.opensource.google/go/go/+/master:src/net/tcpsock.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=22>)
 
<= IPv4len 
<https://cs.opensource.google/go/go/+/master:src/net/ip.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=22>
 
{ 
       return syscall <http://godoc.org/syscall>.AF_INET 
<https://cs.opensource.google/go/go/+/master:src/syscall/zerrors_linux_amd64.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=26>
 
   } 
   if a 
<https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=26>
.IP 
<https://cs.opensource.google/go/go/+/master:src/net/tcpsock.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=22>
.To4 
<https://cs.opensource.google/go/go/+/master:src/net/ip.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=211>()
 
!= nil { 
       return syscall <http://godoc.org/syscall>.AF_INET 
<https://cs.opensource.google/go/go/+/master:src/syscall/zerrors_linux_amd64.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=26>
 
   } 
   return syscall <http://godoc.org/syscall>.AF_INET6 
<https://cs.opensource.google/go/go/+/master:src/syscall/zerrors_linux_amd64.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=27>
 
}
```

So using reasoning above based on silly example looks O.K. but I seems that 
I might be still missing some kind of context/information because I can't 
explain example from STD.

I would like to see what other people approaches this "problem" and to 
learn is there any other rules/guidelines to follow.

Cheers, Deividas

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/b4424465-ea36-4863-8ccf-3631de4ab56an%40googlegroups.com.

Reply via email to