Hello!

The topic of today’s post functions in golang.

Function

In all previous posts, we have used functions multiple times. For example fmt.Println() is a function. Let’s create the simplest function. In golang, there is always a main function, which is the entry point to the program. And accordingly, if we want to call our function, we will add it to the main function

package main

import (
    "fmt"
)

func main() {
    printText()
}

func printText() {
    fmt.Println("Hello")
}

Thus we have two functions main and printText. The printText function is called in the main function. The main function is called when the program starts. Now our function does not accept arguments, let’s try to add a string argument to it

package main

import (
    "fmt"
)

func main() {
    printText("Hello!")
}

func printText(msg string) {
    fmt.Println(msg)
}

If the function accepts an argument, it must be specified when calling the function. Otherwise, there will be an error

$ go run main.go
# command-line-arguments
./main.go:8:2: not enough arguments in call to printText
         have()
         want (string)

More than one argument can be passed, and if those arguments are of the same type, then the type can be specified only once.

package main

import (
    "fmt"
)

func main() {
    printText("Message1", "Message2")
}

func printText(msg, second_message string) {
    fmt.Println(msg, second_message)
}
$ go run main.go
Message1 Message2

If we have a parameter in the main method and we pass it to a function and then change its value, the original value is not changed because golang makes a copy of it.

package main

import (
    "fmt"
)

func main() {
    message := "Hello"
    printText(message)
    fmt.Println(message)
}

func printText(message string) {
    message = "Good Bye"
    fmt.Println(message)
}
$ go run main.go
Good Bye
Hello

But if we need to change the original value, we can pass a pointer.

package main

import (
    "fmt"
)

func main() {
    message := "Hello"
    printText(&message)
    fmt.Println(message)
}

func printText(message *string) {
    *message = "Bye!"
    fmt.Println(*message)
}
$ go run main.go
Bye!
Bye!

If you need to pass many parameters of the same type, you can use ... syntax.

package main

import (
    "fmt"
)

func main() {
    printText("Hello", "Bye")
}

func printText(messages ...string) {
    for _, msg := range messages {
        fmt.Println(msg)
    }
}
$ go run main.go
Hello
Bye

In this case, all the parameters passed to the function will be in the form of a slice.

Return value

In all previous cases, we printed the value of variables directly in the function. If we need to pass the value to another function, we can use the return keyword. And in the function itself, you need to specify what type will be returned.

package main

import "fmt"

func main() {
    result := printText(6, 3)
    fmt.Println(result)
}

func printText(a, b int) int {
    return a / b
}
$ go run main.go
2

Also, if necessary, you can return a pointer.

package main

import (
    "fmt"
)

func main() {
    r := returnPointer()
    fmt.Println(*r)
}

func returnPointer() *int {
    result := 4 / 2
    return &result
}
$ go run main.go
2

Return multiple values

Several values can be returned from the function.

package main

import (
    "fmt"
)

func main() {
    first, second := returnMultiple()
    fmt.Println(first, second)
}

func returnMultiple() (int, int) {
    result := 4 / 2
    secondResult := 6 / 2
    return result, secondResult
}
$ go run main.go
2 3

Return error

Often, the function returns an error in addition to the value. And after that, the calling function is checked to see if there was an error.

package main

import (
    "fmt"
    "log"
)

func main() {
    r, err := returnMultiple(1, 0)
    if err != nil {
        log.Fatalln(err)
    }
    fmt.Println(r)
}

func returnMultiple(a, b int) (int, error) {
    if b == 0 {
        return 0, fmt.Errorf("Cannot divide be zero")
    }
    result := a / b
    return result, nil
}

Anonymous functions

An anonymous function is a function that does not have a name. It is created in the same way as a normal function, only the only thing is that it does not have a name.

package main

import (
    "fmt"
)

func main() {
    func() {
        fmt.Println("Hello")
    }()
}
$ go run main.go
Hello

For the function to be called, you need to add another pair of () at the end. Otherwise, we will get an error

$ go run main.go
# command-line-arguments
./main.go:8:2: func() {} (value of type func()) is not used

If the function does not need to be called immediately, it can be assigned to some parameter and called when needed

package main

import (
    "fmt"
)

func main() {
    a := func() {
        fmt.Println("Hello")
    }
    a()
}
$ go run main.go
Hello

Methods

A method is also a function, but which belongs to a certain type. For example, we have a structure or our type and we can create methods for them. In this example, we have a Hello structure with two fields. Next, we create a function, but additionally before the name of the function we indicate to which type it belongs, in our case, it is a structure named Hello and with the help of the variable h we can refer to its fields. After we have created an instance of this structure in the main method, we can call our method using VARIABLE.METHOD_NAME()

package main

import (
    "fmt"
)

type Hello struct {
    Name    string
    Message string
}

func (h Hello) hello() {
    fmt.Println(h.Message, h.Name)
}
func main() {
    a := Hello{
        Name:    "Maksym",
        Message: "Hello",
    }
    a.hello()
}
$ go run main.go
Hello Maksym

Video