-1

Why do we have the methods declared outside the type definition of the struct? E.g.:

type antenna struct {
    name string
    length float32
    girth float32
    bloodtype string
}

func (p *antenna) extend() {
    p.length += 10
}

It seems to me that the method could be part of the struct? (Let's ignore for now that structs are supposed to be value types)

type antenna struct {
    name string
    length float32
    girth float32
    bloodtype string

    func extend() {
        length += 10
    }
}

This would be more similar to traditional OOP. I didn't find any good explanations of why it is done the way it is besides "structs are value-types and classes are reference-types". I know the difference, but it's not a satisfactory answer to me. In any way the method has to be called like this:

var x = antenna()
x.extend() 

So what's the point of separating the the struct and methods? Having them visually grouped together in the code - as in typical OOP languages - seems useful to me?

Muppet
  • 5,767
  • 6
  • 29
  • 39
  • 3
    You can't just ignore the difference between value and pointer receivers. This is important. Not all methods mutate the receiver. See [time.Time](https://golang.org/pkg/time/#Time) for a prolific example. It's also very useful to be able put types and methods in separate files. This enabled easy code generation and architecture specific implementations. – Peter Nov 20 '18 at 06:42
  • 6
    Any named type can have methods, not just struct types. – Charlie Tumahai Nov 20 '18 at 06:54
  • "This would be more similar to traditional OOP" -- So what? Go isn't OOP. – Jonathan Hall Nov 20 '18 at 07:49

1 Answers1

0

TLR: Code reuse, and Consistency.

1 - This enables to reuse methods:
This is the key design principle of the interface type in Go - let me make it more clear with an example: Consider you need to sort an slice of int (try it here):

    a := []int{1, 3, 2, 5, 4}
    sort.Ints(a)   // sort.Sort(sort.IntSlice(a))
    fmt.Println(a) // [1 2 3 4 5]

You simply call sort.Ints(a) which then calls Sort(IntSlice(a)) inside the standard library:

type IntSlice []int

func (x IntSlice) Len() int           { return len(x) }
func (x IntSlice) Less(i, j int) bool { return x[i] < x[j] }
func (x IntSlice) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }

sort.IntSlice attaches the 3 methods of sort.Interface: Len, Less, and Swap to the type []int, to call:

// Sort sorts data in ascending order as determined by the Less method.
// It makes one call to data.Len to determine n and O(n*log(n)) calls to
// data.Less and data.Swap. The sort is not guaranteed to be stable.
func Sort(data Interface) {
    n := data.Len()
    quickSort(data, 0, n, maxDepth(n))
}

So you are able to reuse methods from the standard library, and you don't need to reimplement it again.


2- You may define your own types, See this example - There is no inside here for this named type - so methods must be outside of this type:

package main

import "fmt"

type num int32

func (p *num) inc() {
    *p++
}

func main() {
    p := num(100)
    p.inc()
    fmt.Println(p) // 101
}

The above named type num versus this user defined type: By design this makes the Go language consistent for both types:


type Animal struct {
    Name  string
    moves []move.Direction
}

func (p *Animal) Walk(dir move.Direction) {
    p.moves = append(p.moves, dir)
}

See also:
In Go is naming the receiver variable 'self' misleading or good practice?

wasmup
  • 14,541
  • 6
  • 42
  • 58
  • 1
    Hi, thanks for your answer. I still don't understand why having the option to define methods inside the struct def would be bad? In C# for example you can define methods both outside and inside and both arrangements have benefits. C# also has value types and the syntax for defining methods is the same as for reference types. So why only allow the methods outside the struct? – Muppet Nov 20 '18 at 16:56
  • @Muppet: it is not bad! It is just by design. each language has its own pros and cons. There are many languages to learn today and one developer should learn many! to get the job done so the inventors of the google decided to build one new fast and simple one! it is simpler than some languages yet has many details to learn and after 3 years I'm still learning Golang! it never ends! and see this [COMPOSITION OVER INHERITANCE](https://flaviocopes.com/golang-is-go-object-oriented/). I hope this helps. – wasmup Nov 20 '18 at 18:37