Go Unit II Functions
Go Unit II Functions
UNIT II
Functions
Functions
1.Parameters and Return Values
2.Call by Value and Reference
3.Named Return Variables
4.Blank Identifiers
5.Variable Argument
Parameters
6.Using defer statements
7.Recursive Functions
8.Functions as Parameters
Functions are generally the block of codes or statements in a program
that gives the user the ability to reuse the same code which
ultimately saves the excessive use of memory, acts as a time saver
and more importantly, provides better readability of the code.
So basically, a function is a collection of statements that perform
some specific task and return the result to the caller.
A function can also perform some specific task without returning
anything.
Function Declaration
Function declaration means a way to
construct a function.
Syntax:
• func: It is a keyword in Go language, which
is used to create a function.
• function_name: It is the name of the
function.
• Parameter-list: It contains the name and
the type of the function parameters.
• Return_type: It is optional and it contain
the types of the values that function
returns. If you are using return_type in your
function, then it is necessary to use a
return statement in your function.
Function Calling
Function Invocation or Function Calling is done when the user wants to execute the
function. The function needs to be called for using its functionality. As shown in the below
example, we have a function named as area() with two parameters. Now we call this
function in the main function by using its name, i.e, area(12, 10) with two parameters.
Example:
// Go program to illustrate the use of function
package main
import "fmt"
// area() is used to find the area of the rectangle area() function two parameters, i.e, length
and width
func area(length, width int)int{
Ar := length* width
return Ar
}
// Main function
func main() {
// call by values
swap(p, q)
fmt.Printf("\np = %d and q = %d",p, q)
}
Call by reference:
Both the actual and formal parameters refer to the same locations, so
any changes made inside the function are actually reflected in actual
parameters of the caller.
Example:
// Go program to illustrate the concept of the call by reference
package main
import "fmt"
// function which swap values
func swap(a, b *int)int{
var o int Output:
o = *a
*a = *b p = 10 and q = 20
*b = o p = 20 and q = 10
return o
}
// Main function
func main() {
var p int = 10
var q int = 20
fmt.Printf("p = %d and q = %d", p, q)
// call by reference
swap(&p, &q)
fmt.Printf("\np = %d and q = %d",p, q)
Go Functions
In Go, functions are the basic building blocks.
A function is used to break a large problem into smaller tasks.
We can invoke a function several times, hence functions promote code
reusability.
There are 3 types of functions in Go:
Output:
120
Named Return Parameters
In Golang, Named Return Parameters are generally termed as the named parameters.
Golang allows giving the names to the return or result parameters of the functions in the
function signature or definition.
Or you can say it is the explicit naming of the return variables in the function definition.
Basically, it eliminates the requirement of mentioning the variables name with the return
statement.
By using named return parameters or named parameters one can only use return keyword at
the end of the function to return the result to the caller.
This concept is generally used when a function has to return multiple values. So for the user
comfort and to enhance the code readability, Golang provide this facility.
Declaring the Named Return Parameters
To declare the named result or return parameters, just use the return type part of the function
signature. Below is the general syntax to declare a function in Golang.
Syntax to declare a function without named return arguments:
func function_name(Parameter-list)(Return_type)
{
// function body.....
}
• If the type of all the named return arguments is common or same then you can
specify the common data type. Compare the below code with the example that
you read above to get a better understandability.
// function having named arguments
func calculator(a, b int) (mul, div int) {
• Here, mul and div variables are both int type. So you can also declare named
arguments with common data type like the function variables(i.e. a and b)
• Using Named return parameters will enhance the code readability as one can
know about the return parameters by just reading the function signature.
• After using named return parameters the return statement is generally termed
as Naked or Bare return.
• By default, Golang defines all the named variables with the zero value and
function will able to use them. In case function doesn’t modify the values then
automatically zero value will return.
• If you will use short declaration operator(:=) to initialize the named return
parameters, it will give an error as they are already initialized by the Go compiler.
So you can use simple assignment(=) to assign the values to named return
parameters.
// function having named arguments
• You can use multiple Blank Identifiers in the same program. So you can say a Golang
program can have multiple variables using the same identifier name which is the
blank identifier.
• There are many cases that arise the requirement of assignment of values just to
complete the syntax even knowing that the values will not be going to be used in the
program anywhere.
Like a function returning multiple values. Mostly blank identifier is used in such cases.
• You can use any value of any type with the Blank Identifier.
Variable Argument Parameters
In Golang, a function that can be called with a variable argument list is known as a variadic function.
One can pass zero or more arguments in the variadic function.
If the last parameter of a function definition is prefixed by ellipsis …, then the function can accept any number of
arguments for that parameter.
Syntax of a variadic function:
Here ... operator tells Golang program to store all arguments of Type in elem
parameter.
Therefore, all the values passed are stored in an elem parameter which is a
slice.
A slice can also be passed in the argument instead of the argument list, as
finally function is converting them into a slice.
Variadic Functions in Go
The function that called with the varying number of arguments is known as variadic
function. Or in other words, a user is allowed to pass zero or more arguments in the
variadic function.
fmt.Printf is the example of the variadic function, it required one fixed argument at the
starting after that it can accept any number of arguments.
Important Points:
In the declaration of the variadic function, the type of the last parameter is preceded
by an ellipsis, i.e, (…). It indicates that the function can be called at any number of
parameters of this type.
Syntax:
Advantages of using a Variadic
Function:
"fmt" {
fmt.Println("Element not present in
) the list")
// Function to check if an elemen is present in the list or not }
func check(x int, v ...int) { }
flag := false
func main() {
index := 0 el := []int{1, 1, 2, 3, 4, 5, 6, 7, 8, 9}
check(1, el...)
for i, j := range v { check(10, el...)
if j == x { }
Output:
flag = true Element 1 found at index: 1
index = i Element not present in the
list
Example
func main() {
fmt.Println(myFunction(1, 2))
}
Example : Named Return Values
Here, we name the return value as result (of type int), and
return the value with a naked return (means that we use
the return statement without specifying the variable name):
package main
import ("fmt")
func main() {
fmt.Println(myFunction(1, 2))
}
Example
func main() {
total := myFunction(1, 2)
fmt.Println(total)
}
Example
Here, we store the two return values into two variables (a and b):
package main
import ("fmt")
func main() {
a, b := myFunction(5, "Hello")
fmt.Println(a, b)
}
Example
Here, we want to omit the first returned value (result - which is stored in
variable a):
package main
import ("fmt")
func main() {
_, b := myFunction(5, "Hello")
fmt.Println(b)
}
Example
Here, we want to omit the second returned value (txt1 - which is stored in
variable b):
package main
import ("fmt")
func main() {
a, _ := myFunction(5, "Hello")
fmt.Println(a)
}
In the following example, testcount() is a function that calls
itself. We use the x variable as the data, which increments
with 1 (x + 1) every time we recurse. The recursion ends
when the x variable equals to 11 (x == 11).
Example
package main
import ("fmt")
Result:
func testcount(x int) int { 1
if x == 11 { 2
return 0 3
} 4
fmt.Println(x) 5
return testcount(x + 1) 6
} 7
8
func main(){ 9
testcount(1) 10
}
Go defer keyword
The defer keyword postpones the execution of a function or statement until the end of
the calling function.
It executes code (a function or expression) when the enclosing function returns before
the closing curly brace }.
It is also executed if an error occurs during the execution of the enclosing function.
In Go language, defer statements delay the execution of the function or method or an anonymous method
until the nearby functions returns.
In other words, defer function or method call arguments evaluate instantly, but they don’t execute until
the nearby functions returns.
You can create a deferred method, or function, or anonymous function by using the defer keyword.
Syntax:
// Function
defer func func_name(parameter_list Type)return_type{ //
Code }
// Method
defer func (receiver Type) method_name(parameter_list){ //
Code }
• In Go language, multiple defer statements are allowed in the same program and they
are executed in LIFO(Last-In, First-Out) order as shown in Example 2.
• In the defer statements, the arguments are evaluated when the defer statement is
executed, not when it is called.
• Defer statements are generally used to ensure that the files are closed when their
need is over, or to close the channel, or to catch the panics in the program.
// Functions
defer fmt.Println("End")
func add(a1, a2 int) int {
defer add(34, 56)
res := a1 + a2
defer add(10, 10) Output:
fmt.Println("Result: ", res) Start
}
return 0 Result: 20
} Result: 90
End
Go defer Example
package main
import (
"fmt"
) Output:
func main() {
defer print1("Hi...")
there
print2("there") Hi...
}
func print1(s string) {
fmt.Println(s)
}
func print2(s string) {
fmt.Println(s)
}
The defer keyword instructs a function to execute after the surrounding
function completes.
Let’s look at a basic example:
package main
import "fmt" func main() {
// When we add `defer` before a function, that function is
executed
// after the surrounding function completes
defer fmt.Println("this is printed once the function
completes")
fmt.Println("this is printed first")
fmt.Println("this is printed second") }
In this case, the “surrounding function” is main
Output:
this is printed first
this is printed second
this is printed once the function
completes
Function Scope
It is important to note that defer is scoped to the function inside which it is declared.
Let’s look at an example where we call another function from inside main :
package main
This is because the deferred function defined in greet is run once greet is completed, whereas the same
func myFunction() {
defer fmt.Println("first")
defer fmt.Println("second")
defer fmt.Println("third")
fmt.Println("starting myFunction...")
// ...
}
starting myFunction...
third
second
first
Each time a function is deferred, it’s pushed onto a stack. Once the
function execution completes, the deferred functions are popped, so that
they execute in a “first-in-first-out” order:
Functions as Parameters
package main
import "fmt"
type Sum struct {
x_val int
y_val int
}
func main() {
// Allocate enough memory to store a Sum structure value and return
a pointer to the value's address
var sum Sum
p := &sum
fmt.Println(p)
// Use a composite literal to perform allocation and
return a pointer to the value's address
p = &Sum{}
fmt.Println(p)
// Use the new function to perform allocation, which will
return a pointer to the value's address.
p = new(Sum) Output
fmt.Println(p) &{0 0}
&{0 0}
}
&{0 0}