Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
3 views

Go Unit II Functions

This document provides an overview of functions in Go programming, covering topics such as function declaration, calling, parameters, return values, and various types of functions including normal, anonymous, and methods. It explains concepts like call by value and reference, named return parameters, and the use of blank identifiers and variadic functions. Additionally, it includes examples to illustrate these concepts in practice.

Uploaded by

hibareshridhar
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Go Unit II Functions

This document provides an overview of functions in Go programming, covering topics such as function declaration, calling, parameters, return values, and various types of functions including normal, anonymous, and methods. It explains concepts like call by value and reference, named return parameters, and the use of blank identifiers and variadic functions. Additionally, it includes examples to illustrate these concepts in practice.

Uploaded by

hibareshridhar
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 61

GO

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() {

// Display the area of the rectangle with method calling


fmt.Printf("Area of rectangle is : %d", area(12, 10))
Output:
}
Area of rectangle is : 120
 Function Arguments
 In Go language, the parameters passed to a function are called actual
parameters, whereas the parameters received by a function are called
formal parameters.
Note: By default Go language use call by value method to pass
arguments in function.
Go language supports two ways to pass arguments to your function:

• Call by value: : In this parameter passing method, values of actual


parameters are copied to function’s formal parameters and the two
types of parameters are stored in different memory locations. So any
changes made inside functions are not reflected in actual parameters of
the caller.
Example:
// Go program to illustrate the concept of the call by value
package main
import "fmt"
// function which swap values
func swap(a, b int)int{
var o int
o= a
Output:
a=b
b=o p = 10 and q = 20
return o p = 10 and q = 20
}
// Main function
func main() {
var p int = 10
var q int = 20
fmt.Printf("p = %d and q = %d", p, q)

// 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:

1. Normal functions with an identifier


2. Anonymous or lambda functions
3. Method (A function with a receiver)

 Function parameters, return values, together with types, is called function


signature.
 Function cannot be declared inside another function. If we want to achieve
this, we can do this by anonymous function.
Go Function Example
package main
import "fmt"
type Employee struct {
fname string
o/p:
lname string
}
John Ponting
func (emp Employee) fullname(){
fmt.Println(emp.fname+" "+emp.lname)
}
func main() {
e1 := Employee{ "John","Ponting"}
e1.fullname()
}
Go Function with Return
Let's see an example of function with return value.
package main
import (
"fmt"
)
Output:
func fun() int {
123
return 123456789
}
func main() {
x := fun()
fmt.Println(x)
}
Go Function with Multiple Return
Let's see an example of a function which takes n number of type int as
argument and returns two int values. The return values are filled in the
calling function in a parallel assignment.
Go function multiple return example Outp
package main ut:
import (
"fmt" 100 -
)
func main() {
fmt.Println(addAll(10,15,20,25,30))
100
}
func addAll(args ... int)(int,int) {
finalAddValue:=0
finalSubValue:=0
for _,value := range args{
finalAddValue += value
finalSubValue -= value
}
return finalAddValue,finalSubValue
}
Go Recursion
In Go programming, calling same function from within the function is known as recursion. It is
always a good idea to break a problem into multiple tasks. Let us see a program to calculate
factorial value in Go programming using recursion.
Go Recursion Example: Factorial Number
package main
import (
"fmt"
)
func main() {
fmt.Println(factorial(5))
}
func factorial(num int ) int{
if num == 0{
return 1
}
return num*factorial(num-1)
}

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.....
}

Here, the Return_Type is optional and it contains the types of


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.
 Syntax to declare a function with named return arguments:
func function_name(Parameter-list)(result_parameter1 data-_type,
result_parameter2 data_type, ….)
{
// function body…..
return
}

 Here, (result_parameter1 data-_type, result_parameter2 data_type,


….) is the named return argument list along with their type.
 You can declare n number of named return parameters.
 Example:
 In the below program, the func calculator(a, b int) (mul int, div int) line of code
contains the named return arguments.
 The return statement at the end of function doesn’t contain any parameters.
 Go compiler will automatically return the parameters.
// Golang program to demonstrate the use of Named Return Arguments
package main
import "fmt"
// Main Method
func main() {
// calling the function, here function returns two values
m, d := calculator(105, 7)
fmt.Println("105 x 7 = ", m)
fmt.Println("105 / 7 = ", d)
}
// function having named arguments
func calculator(a, b int) (mul int, div int) {
// here, simple assignment will initialize the values to it
mul = a * b
div = a / b
// here you have return keyword without any resultant parameters
return
}
Important Points

• 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

func calculator(a, b int) (mul int, div int) {


// here, it will give an error
// as parameters are already defined
// in function signature
mul := a * b div := a / b
// here you have return keyword
// without any resultant parameters
return
}
• Named return arguments or bare return statements are only good for
the short function signature.
• For longer functions, explicitly return the result parameters(not use
named return parameters) to maintain the readability of the code.
• In the case of named return arguments, bare or naked return
statement is a must.
Blank Identifier(underscore) in Golang?

 _(underscore) in Golang is known as the Blank Identifier. Identifiers


are the user-defined name of the program components used for the
identification purpose.
 Golang has a special feature to define and use the unused variable
using Blank Identifier.
 Unused variables are those variables that are defined by the user
throughout the program but he/she never makes use of these
variables.
 These variables make the program almost unreadable.
 As you know, Golang is a more concise and readable programming
language so it doesn’t allow the programmer to define an unused
variable if you do such, then the compiler will throw an error.
 The real use of Blank Identifier comes when a function returns
multiple values, but we need only a few values and want to discard
some values.
 Basically, it tells the compiler that this variable is not needed and
ignored it without any error.
 It hides the variable’s values and makes the program readable.
 So whenever you will assign a value to Blank Identifier it becomes
unusable.
 Example 1: In the below program, the function mul_div is returning
two values and we are storing both the values
in mul and div identifier. But in the whole program, we are using only
one variable i.e. mul. So compiler will throw an error div declared and
not used
// Golang program to show the compiler throws an error if a variable
is declared but not used
package main
import "fmt"
// Main function
func main() {
// calling the function function returns two values which are assigned
to mul and div identifier
mul, div := mul_div(105, 7)
// only using the mul variable compiler will give an error
fmt.Println("105 x 7 = ", mul) o/p:
}
./prog.go:15:7: div declared and
// function returning two values of integer type
not used
func mul_div(n1 int, n2 int) (int, int) {
// returning the values
return n1 * n2, n1 / n2
}
 Example 2: Let’s make use of the Blank identifier to correct the
above program. In place of div identifier just use the _ (underscore). It
allows the compiler to ignore declared and not used error for that
particular variable.
// Golang program to the use of Blank identifier
package main
import "fmt"
// Main function
func main() {
// calling the function function returns two values which are assigned to mul and blank
identifier
mul, _ := mul_div(105, 7)
// only using the mul variable
Output:
fmt.Println("105 x 7 = ", mul)
} 105 x 7 = 735
// function returning two values of integer type
func mul_div(n1 int, n2 int) (int, int) {
// returning the values
return n1 * n2, n1 / n2
}
Important Points:

• 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:

func f(elem ...Type)

Here ... operator tells Golang program to store all arguments of Type in elem
parameter.

After that, Go create an elem variable of the type []Type.

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:

• Passing a slice in a function is very easy.


• Useful when the number of parameters is unknown.
• Increases the readability of the program.
 Let’s see some of the examples to use functions with variable
argument list:
Example 1:

// Go program that uses a function with variable argument list


package main
// Importing required packages
import (
"fmt"
)
// Variadic function to return the sum of the numbers
func add(num ...int) int {
sum := 0 Output:
for j := range num { Sum = 45
sum += j
}
return sum
}
func main() {
fmt.Println("Sum =", add(1, 2, 3, 4, 5, 7, 8, 6, 5, 4))
}
Example 2: A slice can also be used as an argument list.

// Go program that uses a function with variable argument if flag {


lis Using a slice as the argument list
fmt.Println("Element ", x, " found at
package main index:", index)
// importing required modules }
import ( else

"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

Here, myFunction() receives two integers (x and y) and


returns their addition (x + y) as integer (int):
package main
import ("fmt")

func myFunction(x int, y int) int {


return x + y
}

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 myFunction(x int, y int) (result int) {


result = x + y
return
}

func main() {
fmt.Println(myFunction(1, 2))
}
Example

Here, we store the return value in a variable called total:


package main
import ("fmt")

func myFunction(x int, y int) (result int) {


result = x + y
return
}

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 myFunction(x int, y string) (result int, txt1 string) {


result = x + x
txt1 = y + " World!"
return
}

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 myFunction(x int, y string) (result int, txt1 string) {


result = x + x
txt1 = y + " World!"
return
}

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 myFunction(x int, y string) (result int, txt1 string) {


result = x + x
txt1 = y + " World!"
return
}

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 is generally used for cleaning purpose.

 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 }

defer func (parameter_list)(return_type){


// code }()
Important Points:

• 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.

 Let us discuss this concept with the help of an example:


Example 1:
// Main function
// Go program to illustrate the concept
of the defer statement func main() {
package main // Calling mul() function
import "fmt" // Here mul function behaves like a
// Functions normal function
func mul(a1, a2 int) int { mul(23, 45)
// Calling mul()function Using defer
res := a1 * a2 keyword
fmt.Println("Result: ", res) // Here the mul() function is defer
return 0 function
}
defer mul(23, 56)
func show() {
fmt.Println("Hello!,
GeeksforGeeks") // Calling show() function
Output:
Result: 1035
} show()
Hello!, GeeksforGeeks
} Result: 1288
 Explanation:
 In the above example we have two functions named mul() and show().
 Where show() function is called normally in the main() function, mul() function is
called in two different ways:
• First, we call mul function normally(without the defer keyword), i.e, mul(23, 45) and it
executes when the function is called
(Output: Result : 1035 ).
• Second, we call mul() function as a defer function using defer keyword, i.e,
defer mul(23, 56) and it executes
(Output: Result: 1288 ) when all the surrounding methods return.
Example 2: // Main function
// Go program to illustrate func main() {
// multiple defer statements, to illustrate
LIFO policy
fmt.Println("Start")
package main

// Multiple defer statements


import "fmt"
// Executes in LIFO order

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

import "fmt" func main() {

defer fmt.Println("this is printed once main completes")


greet()
fmt.Println("this is printed after greet is called")
}
func greet() {
// this function executes once `greet()` completes.

// It is independent of deferred functions declared elsewhere


defer fmt.Println("printed after the first greeting")
fmt.Println("first greeting")
}

This gives us the output:


// first greeting
// printed after the first greeting
// this is printed after greet is called
// this is printed once main completes

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...")
// ...
}

What will be the output When myFunction is called?


O/P

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

 Golang function are first-order variables meaning that


• They can be assigned to a variable
• Passed around as function argument
• Returned from a function

 In GO function is also a type.


 Two functions are of the same type if they have the same arguments and the same return values.
 While passing a function as an argument to another function, the exact signature of the function has
to be specified in the argument list.
 As in below example print function accept first argument which is a function of type func(int, int) int

func print(f func(int, int) int, a, b int)


Some more things to note about the below program
• function area is a function of func(int, int) int
• function sum is a function of type func(int, int) int
• area and sum are of same type as they have same arguments type and same return
values type
• print function accepts a function as its first argument of type func(int, int) int
• Thus both area and sum function can be passed as an argument to
the print function.
Code:
package main
import "fmt" func main() {
print(area, 2, 4)
print(sum, 2, 4)
}

func print(f func(int, int) int, a, b int) {


fmt.Println(f(a, b))
}

func area(a, b int) int { Output


return a * b 8
}
6
func sum(a, b int) int {
return a + b
}
new() and make().
 In Golang, to allocate memory, we have two built-in functions new() and
make().
1) new() function
• Memory returned by new() is zeroed.
• new() only returns pointers to initialized memory.
• new() works for all the data types (except channel, map), and dynamically
allocates space for a variable of that type and initialized it to zero value of
thatExample:
type and return a pointer to it.
result = new(int)
is equivalent to
var temp int // declare an int type variable
var result *int // declare a pointer to int
result = &temp
Example/program:
There are three different ways to create a pointer that points to a zeroed structure value, each of which is equivalent:

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}

You might also like