Whats the difference of functions and methods in Go?
Asked Answered
E

6

90

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 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?

Edible answered 24/11, 2011 at 23:44 Comment(1)
The terms "method" and "function" are just historical conventions. The plain language implies "how" versus "what" which is not the case, and therefore confusing. We might believe "function" is mathematical, but that's also not the case, and therefore confusing. The truth is "method" was just adopted from OO languages as being associated with a particular type, while "function" was adopted from procedural languages where the function is free-standing. I think you can see those simple explanations hold in go: method is invoked on a type, function is not.Interrupt
L
139

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)
Leupold answered 25/11, 2011 at 0:15 Comment(7)
I wouldn't say that "Go isn't an OOP language". Go IMHO just favors composition over inheritance so much that it provides extra syntatic sugar for the former and has gotten rid of the latter completely.Lixivium
I'm not sure about that. Imho, part of the OOP paradigm is also subclassing + type hierarchies. That's just not possible with Go (luckily!). Sure, Go provides other ways (i.e. embedding) to solve similar problems, but they are no 1:1 replacement. But let's stop the terminology-bikeshedding :DLeupold
Thanks, I finally got it! A missing piece was, that methods are always used in conjunction with a type.Edible
@Leupold thank you for the examples. One problem, your method contains an invalid operation: a + b (mismatched types MyInteger and int). In order for this to work you would need to cast either a to be an int or b to be a MyInteger. For example: return int(a) + b or return a + MyInteger(b). In the second case, you would need to change the return value type in the method signature to be MyInteger instead of int. playgroundPoseur
I would point out the sentence states: "Go isn't an OOP language in the classical meaning" not that it is not an OOP languageDockyard
Go isn't a classic OOP language. Forget about encapsulation, polymorphism, and inheritance which you can implement in Go (even though there is no embedded into a language mechanism for easy implementation of these characteristics). Think of Object oriented programming. Object in this sentence is a class and since in Go function is a first-class citizen and they can exist without being a part of the class, you cannot call Go as a classic OOP languageHuda
So there are two ways to look at OOP. The original definition had nothing to do with classes or inheritance. Whether or not Alan Kay would consider Go an OO language is not entirely sure, because it misses the "extreme late binding of things" part. For the rest Kay said the important concept was objects passing messages. Go does that, well. youtube.com/watch?v=HqZQBmNVhBw <- A good talk about this. If you choose to follow Bjarne Stroustrup's OOP, then sure, classes, inheritance, etc.Anchusin
A
31

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.

Aryanize answered 22/11, 2015 at 8:8 Comment(2)
Is there any functional difference between a function with a pointer argument vs a method? Are methods just syntactic sugar?Riproaring
If function can do all the stuffs like you listed above, i still don't understand the point to use methodSchilt
C
24

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.

Calculous answered 1/2, 2017 at 8:10 Comment(1)
just wondering, that would defeat the purpose as the whole argument on immutability is not to modify the value?Willywillynilly
Y
0

Go methods are similar to Go function with one difference, i.e, the method contains a receiver argument in it. With the help of the receiver argument, the method can access the properties of the receiver. Here, the receiver can be of struct type or non-struct type.

func(reciver_name Type) method_name(parameter_list)(return_type){
    // Code
}
Yokefellow answered 24/10, 2022 at 3:10 Comment(0)
K
0

Above answer seems good to me. Along with that I would also like to add on it.

Function is something which is invoked from package. Whereas method is also a function but invoked from particular type values. And values is the return of functions.

For example:

  1. rightNow := time.Now()

time --> package, Now() --> function because invoked by a package, rightNow is the value of type time.Time returned from Now() function.

  1. year := rightNow.Year()

rightNow --> value, Year() --> function but since it is invoked by a value of some type(here time.Time), therefore it is called a Method. For easily identication Method has a reciever of that same type from which it is invoked.

Ky answered 8/11, 2022 at 7:14 Comment(0)
C
-2

The words function and method are used almost interchangeably, but there are subtle differences in their implementation and usage when used in Golang . Hailing from Java or any other object-oriented language background, the first instinct is to use structs and methods for everything since objects always have a behaviour defined by their methods .

But is that a right approach in Golang where we have functions and methods both ? Let’s first understand what is a function and what is a method in Golang .

A function takes a few parameters as input and produces some output. For the same input, the function will always produce the same output. That means it’s not dependent on the state. Type is always passed as an argument to the function .

Cementum answered 1/4, 2024 at 6:58 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.