Whats the difference of functions and methods in Go?

后端 未结 3 1407
独厮守ぢ
独厮守ぢ 2020-11-28 05:26

I am trying to get started with Go and the documentation is very good. What I did not find in the documentation is the difference between functions and methods.

As f

相关标签:
3条回答
  • 2020-11-28 05:33

    As far as I understand at the moment: functions are "global", which means I do not have to import a package to use functions, they are always there. Methods are bound to packages. Is this correct?

    No, that's not correct. There are just a couple of functions from the builtin package which are always available. Everything else needs to be imported.

    The term "method" came up with object-oriented programming. In an OOP language (like C++ for example) you can define a "class" which encapsulates data and functions which belong together. Those functions inside a class are called "methods" and you need an instance of that class to call such a method.

    In Go, the terminology is basically the same, although Go isn't an OOP language in the classical meaning. In Go, a function which takes a receiver is usually called a method (probably just because people are still used to the terminology of OOP).

    So, for example:

    func MyFunction(a, b int) int {
      return a + b
    }
    // Usage:
    // MyFunction(1, 2)
    

    but

    type MyInteger int
    func (a MyInteger) MyMethod(b int) int {
      return a + b
    }
    // Usage:
    // var x MyInteger = 1
    // x.MyMethod(2)
    
    0 讨论(0)
  • 2020-11-28 05:45

    Tux's answer is great, but I want to augment it with the usage of Go's methods with structs (because this is where I used it often). So let's assume you want to build something to calculate various methods on triangles. You start with a struct:

    type Triangle struct {
        a, b, c float64
    }
    

    and then you would like to add some functions to calculate the perimeter and square:

    func valid(t *Triangle) error {
        if t.a + t.b > t.c && t.a + t.c > t.b && t.b + t.c > t.a {
            return nil
        }
        return errors.New("Triangle is not valid")
    }
    
    func perimeter(t *Triangle) (float64, error) {
        err := valid(t)
        if err != nil {
            return -1, err
        }
    
        return t.a + t.b + t.c, nil
    }
    
    func square(t *Triangle) (float64, error) {
        p, err := perimeter(t)
        if err != nil {
            return -1, err
        }
    
        p /= 2
        s := p * (p - t.a) * (p - t.b) * (p - t.c)
        return math.Sqrt(s), nil
    }
    

    And now you got your working program Go Playground. In this case your function takes a parameter (pointer to a triangle) and does something. In OOP word people might have created a class and then added methods. We can see our struct as kind of class with fields and now we add methods:

    func (t *Triangle) valid() error {
        if t.a + t.b > t.c && t.a + t.c > t.b && t.b + t.c > t.a {
            return nil
        }
        return errors.New("Triangle is not valid")
    }
    
    func (t *Triangle) perimeter() (float64, error) {
        err := t.valid()
        if err != nil {
            return -1, err
        }
    
        return t.a + t.b + t.c, nil
    }
    
    func (t *Triangle) square() (float64, error) {
        p, err := t.perimeter()
        if err != nil {
            return -1, err
        }
    
        p /= 2
        s := p * (p - t.a) * (p - t.b) * (p - t.c)
        return math.Sqrt(s), nil
    }
    

    and we have a fully working example.

    Notice that it looks really like a method for objects.

    0 讨论(0)
  • 2020-11-28 05:51

    They are explained in detail here - https://anil.cloud/2017/01/26/golang-functions-methods-simplified/

    A function in Go follows the syntax:

    func FunctionName(Parameters...) ReturnTypes...
    

    Example:

    func add(x int, y int) int
    

    To execute:

      add(2,3) 
    

    A method is like a function, but attached to a type (called as receiver). The official guide states “A method is a function with a special receiver argument”. The receiver appears in between the func keyword and the method name. The syntax of a method is:

    func (t ReceiverType) FunctionName(Parameters...) ReturnTypes...
    

    Example:

    func (t MyType) add(int x, int y) int
    

    To execute:

    type MyType string
    t1 := MyType("sample")
    t1.add(1,2)
    

    Now lets bring pointers into the table. Go lang is pass by value, means fresh copies of the parameters are passed to each function/method call. To pass them by reference you can use pointers.

    Syntax of function with pointer in argument/parameter list.

    func FunctionName(*Pointers...,Parameters...) ReturnTypes...
    

    Example

    func add(t *MyType, x int, y int) int
    

    To execute:

    type MyType string
    t1 := MyType("sample")
    add(&t1,4,5)
    

    Similarly for methods, the receiver type can be a pointer. Syntax of method with pointer (as receiver)

    func (*Pointer) FunctionName(Parameters...) ReturnTypes...
    

    Example

    func (t *MyType) add(x int, y int) int
    

    To execute:

    type MyType string
    t1 := MyType("sample")
    t1.add(2,3)
    

    Note that we can still write t1.add() to execute the method with a pointer receiver(even-though ‘t1’ is not a pointer) and Go will interpret it as (&t1).add(). Similarly a method with value receiver can be called using pointer too, Go will interpret p.add() as as (*p).add() in that case (where ‘p’ is a pointer). This is applicable only for methods and not for functions.

    Methods with pointer receiver are very useful to get a “Java” like behavior where the method is actually modifying on the value to which the receiver points and not on a copy of it.

    0 讨论(0)
提交回复
热议问题