Go: All About Functions (Part 6)

This is a sixth post on Go programming language. You can read first, second, third, forth and fifth post if you are reading this post for the first time. These posts will give you necessary background.

In Go, we can write the re-usable code inside the functions! We already know how to write the functions because from the beginning, we are writing main() function. The function can be created using func keyword followed by name with parenthesis. This parenthesis may be empty or it might contains take some parameters. After the parenthesis, you writes the body of function within curly braces. For example,

func hello() {

}

To call this function, you just need to write function name with parenthesis. For example,

func hello() {

}

hello()

Let's write a complete program greet.go to better understand this concept in action.

package main

import "fmt"

func hello() {
    fmt.Println("hello, world. Good to see you!")
}

func main() {
    hello()
}

In the above program, we are calling hello() function from the main() function. If we run this program, it will generate -

$ go run greet.go
hello, world. Good to see you!

The order of function doesn't matter. You can write the function before its usage like I did in above program or you can write it after the calling. You can try that by changing the location of function hello().

Functions accept parameters. But, being static typed programming language, you need to define the type of parameters. For example, our hello() function can accept name as parameter and we can define this as,

package main

import "fmt"

func hello(name string) {
    fmt.Println("hello, world. Good to see you!")
}

func main()  {
    hello()
}

Pay attention on how I define the parameter - name of the parameter and then type. We also need to update our calling function with argument. Let's pass the name "Bruce". But, we are not doing anything with name. Why not update the greeting text with name instead of static world. The complete update in program should look like this.

package main

import "fmt"

func hello(name string) {
    fmt.Println("hello,", name ,". Good to see you!")
}

func main()  {
    hello("Bruce")
}

Running this program will generate following output.

$ go run greet.go
hello, Bruce . Good to see you!

You can pass more than one parameters to function. In this case, all parameters should be separated by comma operator like -

func hello(firstName string, lastName string) {
    fmt.Println("hello," , firstName, lastName, ". Good to see you!")
}

Instead of printing something on terminal, you can return the value from the function using return keyword and then use that return value to print the output. Again, you need to tell via function definition that what type of value you are returning. You can write this after parenthesis and before opening curly brace. For example,

func si(p float64, r float64, n float64) (float64) {
    return p * r * n / 100
}

Here, if you are returning only one value then you can omit the parenthesis for return type. But, just for the simplicity, I didn't.

This function calculate the simple interest. But, instead of printing the calculated interest it return the interest. You can now use this return value in the way you want. Here is the complete si_func.go program that demonstrate the return statement.

package main

import "fmt"

func main() {
    var interest float64
    interest = si(1000, 10, 1)

    fmt.Println("You need to pay", interest, "as interest")
}

func si(p float64, r float64, n float64) (float64){
    return p * r * n / 100
}

We know the shorthand for variable, :=. Right. That make our program much easier as,

package main

import "fmt"

func main() {
    interest := si(1000, 10, 1)

    fmt.Println("You need to pay", interest, "as interest")
}

func si(p float64, r float64, n float64) (float64){
    return p * r * n / 100
}

We just don't have to worried out the type of value, function returns.

If needed then you can also return multiple values from the single function. Lets say, I want to calculate the area of circle and the diameter of circle then I can do as in area_and_diameter.go -

package main

import "fmt"

func AreaAndDiameter(r float64) (float64, float64){
    pi := 3.14

    area := pi * r * r

    diameter := r * 2

    return area, diameter
}

Here, first I define function with types that this function return values e.g. float64 and float64. Then within function, I'm returning the values of this function using comm operator like I did in the last line in the above function.

We can call this AreaAndDiameter() function by passing the radius of circle. But, how we can get the return values? Simple as -

area, diameter := AreaAndDiameter(10)

And finally we can use these values to do whatever we want with them. Here is the complete example -

package main

import "fmt"

func AreaAndDiameter(r float64) (float64, float64) {
    pi := 3.14

    area := pi * (r * r)

    diameter := r * 2

    return area, diameter
}

func main() {
    area, diameter := AreaAndDiameter(10)

    fmt.Println("The area of circle is", area, "and diameter is", diameter, ".")
}

That's it for the functions. The floor is no open for questions.

Can I write the opening curly brace in next line while creating the function?: I'm not going to answer this question. You can easily check this by running the modification.

How many values I can return from function? As I pointed out - minimum 0 and maximum 2. The idea is, in future you might write the function that return result and error if occurs any. In this case you can handle both properly. So, at max 2 values can be return.

In your area_and_diameter.go program you define area twice - first in that function and second in main() function. Is it cause any problem?: Nope. Because the scope are different. You can define same variable name in two different functions and it works without any problem.

AreaAndDiameter() function return two values. But, at some places I just only want one value diameter. Do I still need to define another variable because function return?: Yes. You must need to define two variable to get the values from function. But, you can use blank identifier or _ at the place of area variable. Because, you don't need it right? That way you can ignore the value you don't want.

In si-func.go you write a function that take the p, r and n values with same type. Can we write it in short way because we are copying float64 three times?: You are asking this question that mean you already know. Anyway, you can write as - si(p, r, n float64) and it will works.

The syntax for defining function is little odd: Because, we are from C-family background. Only practice make this syntax more familiar.