2
2
.
.
5
5
.
.
1
1
F
F
u
u
n
n
c
c
t
t
i
i
o
o
n
n
D
D
e
e
c
c
l
l
a
a
r
r
a
a
t
t
i
i
o
o
n
n
-
-
N
N
a
a
m
m
e
e
d
d
I
I
n
n
f
f
o
o
[
[
R
R
]
]
[
[
R
R
]
]
Function Declaration declares Named Function (Function that has a Name)
Each Function has Signature which defines
Data Types of Input Parameters (name:String, age:Int)
Data Type of Return Value (String)
Colon ":" inside Signature symbolizes that these Input Parameters are converted into this Output Parameter.
Since Functions can be stored inside Variables or given as Input Parameters into other Functions, Signature is used to say
what kind of Function can be stored into a Variable
what kind of Function can be given as Input Parameter into another Function
For instance var name : Int says that this Variable can store Int Data Type.
Similarly var name : (name:String, age:Int) -> (String) says that this Variable can store Function that
accepts String & Int as Input Parameters
returns String
Content
Syntax - Block fun greet (name:String, age:Int) : (String) { ... }
Syntax - Assignment fun greet (name:String, age:Int) : (String) = Single Line
Input Parameters fun greet (name:String, age:Int, height: Int = 170) greet("John", age=20)
Return Value fun greet1(name: String, age: Int) : Unit { ... }
Function Scope (Top Level, Local, Member, Extension Functions)
Function as Input Parameter
Function as Return Value
Infix Methods (Methods with single Parameter, no default value, no vararg)
Syntax
//NAMED FUNCTION DECLARATIONS.
fun greet (name:String, age:Int = 20) : (String) { return("$name is ${age} years old") }//Block Syntax
fun greet (name:String, age:Int) : (String) = "$name is ${age} years old" //Assignment Syntax
//CALL FUNCTION BY NAME.
greet(name="John", age=50) //Named Parameters
greet("John", age=50) //Indexed before Named Parameters
greet("John", 50) //Indexed Parameters
greet("John") //Default Parameters
S
S
y
y
n
n
t
t
a
a
x
x
-
-
B
B
l
l
o
o
c
c
k
k
Function Declaration
uses Keyword fun fun
followed by Function's Name greet
followed by Function's Signature (name:String, age:Int) : (String) (accepts 2 Parameters & returns String)
followed by Function's Body { return("$name is $age years old.") } (requires return Keyword)
Block Syntax
//DECLARE & IMPLEMENT FUNCTION.
fun greet (name:String, age:Int) : (String) { return("$name is $age years old.") }
//CALL FUNCTION.
var result = greet("John", 50)
//DISPLAY RESULT.
print(result)
S
S
y
y
n
n
t
t
a
a
x
x
-
-
A
A
s
s
s
s
i
i
g
g
n
n
m
m
e
e
n
n
t
t
Function is declared by
using Keyword fun fun
followed by Function's Name greet
followed by Function's Signature (name:String, age:Int) : (String) (accepts 2 Parameters & returns String)
followed by equal sign "=" "="
followed by single statement "$name is $age years old." (forbidden return Keyword)
Assignment Syntax
//DECLARE & IMPLEMENT FUNCTION.
fun greet (name:String, age:Int) : (String) = "$name is $age years old."
//CALL FUNCTION.
var result = greet("John", 50)
//DISPLAY RESULT.
print(result)
I
I
n
n
p
p
u
u
t
t
P
P
a
a
r
r
a
a
m
m
e
e
t
t
e
e
r
r
s
s
[
[
R
R
]
]
Function Input Parameters
can have default values greet (height: Int = 170)
can be called without their names greet("John", 20)
such Indexed Parameters must be given in the same order in which they are declared in a Function
can be called with their names in which case greet(age=20, name="John")
order of such Named Parameters doesn't matter
default parameters can be at any position
can be called with the combination of Indexed & Named Parameters in which case greet("John", age=20)
Indexed Parameters need to come before the Named Parameters
Default, Indexed & Named Parameters
//DECLARE FUNCTION WITH DEFAULT PARAMETER.
fun greet (name:String, age:Int, height: Int = 170) : Unit {
print("$name is $age years old and $height cm tall.")
}
//CALL FUNCTION.
greet("John", 20) //Parameters can be specified without their names. Then order matters.
greet("John", age=20) //When mixing Indexed & Named Parameters, Indexed Parameters need to come first.
greet(age=20, name="John") //When using named Parameters order doesn't matter
V
V
a
a
r
r
i
i
a
a
b
b
l
l
e
e
N
N
u
u
m
m
b
b
e
e
r
r
o
o
f
f
A
A
r
r
g
g
u
u
m
m
e
e
n
n
t
t
s
s
Function can have one vararg Parameter
vararg must be first fun sum(vararg numbers: Int, base: Int)
vararg is internally represented as Array<T>
other Parameters must be called with their names (Named Parameters) sum(1, 2, 3, 4, base = 100)
Array elements can be passed using star "*" prefix *numbers sum(*numbers, base = 100)
Variable Number of Arguments
//DECLARE FUNCTION WITH VARARG PARAMETER.
fun sumOfNumbers(vararg numbers: Int, baseNumber: Int) : Unit {
var sum : Int = baseNumber
for(number in numbers) { sum += number }
println(sum)
}
//CALL FUNCTION WITH VARIABLE NUMBER OF ARGUMENTS.
sumOfNumbers(1, 2, 3, 4, baseNumber = 100) //Other Parameters must be called with their names
When using Array to provide elements to vararg Parameter you can use spread operator (*) which only works on intArray.
From intArray
//CALL FUNCTION WITH ARRAY ELEMENTS.
val numbers : IntArray = intArrayOf(1, 2, 3, 4)
sumOfNumbers(*numbers, baseNumber = 100) //vararg Parameter can be loaded with Array Elements
If you have Array<Int> you have to convert it first.
From Array<Int>
//CALL FUNCTION WITH ARRAY ELEMENTS.
var numbers : Array<Int> = arrayOf<Int>(1, 2, 3, 4)
sumOfNumbers(*numbers.toIntArray(),baseNumber=10) //vararg Parameter can be loaded with Array Elements
R
R
e
e
t
t
u
u
r
r
n
n
V
V
a
a
l
l
u
u
e
e
[
[
R
R
]
]
Functions only have a single Return Value. Return Value Data Type is part of their Signature.
U
U
n
n
i
i
t
t
Functions which dont return anything have a return type of Unit (corresponds to void in Java).
If Function doesn't return any value you don't need specify Unit in the Signature and you don't need return Keyword.
Unit
fun greet1(name: String, age: Int) : Unit { print("$name is $age years old") }
fun greet2(name: String, age: Int) { print("$name is $age years old") }
greet1("John", 20)
F
F
u
u
n
n
c
c
t
t
i
i
o
o
n
n
S
S
c
c
o
o
p
p
e
e
[
[
R
R
]
]
Based on Scope Kotlin Functions can be
Top Level Functions (Can be defined at the top level inside a source file outside any Object or Class)
Local Functions (Functions defined inside another Function)
Member Functions (Methods defined inside an Object or Class)
Extension Functions (Methods added to an existing Object or Class through Extensions)
Function Scope
//===========================================================================================================
// DECLARE FUNCTIONS
//===========================================================================================================
fun topLevelFunction() { println("Top level Function") } //Top level Function
fun outerFunction() {
fun localFunction() { println("Local/Inner Function") } //Local/Inner Function
localFunction()
}
class Person {
fun memberFunction() { println("Member Function") } //Member Function (Method)
}
fun Person.extensionFunction() { println("Extension Function") } //Extension Function
//===========================================================================================================
// CALL FUNCTIONS
//===========================================================================================================
fun main() {
topLevelFunction() //Top level Function
outerFunction() //Calls Local/Inner Function
var person = Person()
person.memberFunction() //Member Function (Method)
person.extensionFunction() //Extension Function
}
F
F
u
u
n
n
c
c
t
t
i
i
o
o
n
n
a
a
s
s
I
I
n
n
p
p
u
u
t
t
P
P
a
a
r
r
a
a
m
m
e
e
t
t
e
e
r
r
When you compare this code with Lambda Expressions as Function Parameter you see that
using Lambda Expression allows us to declare and use Anonymous Function in the place of Input Parameter
using Function Declaration we first need to declare the Named Function and then use its Name as Input Parameter
Lambda Expressions as Function Parameter
executeFunction({ name: String, age: Int -> "$name IS $age YEARS OLD." })
Function as Input Parameter
//===========================================================================================================
// FUNCTION: executeFunction
//===========================================================================================================
fun executeFunction(receivedFunction: (name: String, age: Int) -> String) {
var result = receivedFunction("John", 20)
println(result)
}
//===========================================================================================================
// FUNCTION: main
//===========================================================================================================
fun main() {
//DECLARE LOCAL VARAIBLE.
var weight = 150
//DECLARE NAMED FUNCTION.
fun namedFunction (name: String, age: Int) : String {
return("$name is $age years old and $weight kg.")
}
//USE NAMED FUNCTION AS PARAMETER (SENDS CLOSURE WITH weight Property).
executeFunction(::namedFunction)
}
F
F
u
u
n
n
c
c
t
t
i
i
o
o
n
n
a
a
s
s
R
R
e
e
t
t
u
u
r
r
n
n
V
V
a
a
l
l
u
u
e
e
Function getFunction() actually returns a Closure with
this Named Function as its Method
Property weight which is declared outside of the Scope of Named Function
When you compare this code with Lambda Expressions as Return Value you see that
using Lambda Expression allows us to declare and return Anonymous Function in one line
using Function Declaration we first need to declare the Named Function and then use its Name to return it
Lambda Expressions as Return Value
return { name: String, age: Int -> "$name is $age years old and $weight kg." }
Function as Return Value
//===========================================================================================================
// FUNCTION: getFunction
//===========================================================================================================
fun getFunction (weight: Int) : (name: String, age: Int) -> String {
//DECLARE NAMED FUNCTION.
fun returnedFunction(name: String, age: Int) : String {
return "$name is $age years old and $weight kg."
}
//RETURN NAMED FUNCTION.
return ::returnedFunction
}
//===========================================================================================================
// FUNCTION: main
//===========================================================================================================
fun main() {
//DECLARE VARIABLE TO HOLD FUNCTION DATA TYPE.
var returnedFunction : (name: String, age: Int) -> String
//DECLARE ANONYMOUS FUNCTION USING LAMBDA EXPRESSION.
returnedFunction = getFunction(150) //Returns Closure with partialy initialized Function
//CALL RETURNED FUNCTION.
var result = returnedFunction("John", 20) //Call Function with missing Parameters
//DISPLAY RESULT.
print(result)
}
I
I
n
n
f
f
i
i
x
x
M
M
e
e
t
t
h
h
o
o
d
d
s
s
[
[
R
R
]
]
Infix Method is declared like any other Method except that it has Keyword infix.
You can also call it like a normal Method but also in this special infix way by omitting dot and parentheses.
Infix Methods
must be member or extension functions (Methods)
must have a single parameter
Parameter can't have default value
Parameter can't be vararg (can't accept variable number of arguments)
Infix Method
//===========================================================================================================
// CLASS: Person
//===========================================================================================================
class Person(var age: Int) {
infix fun addAge(age: Int) : Int {
return this.age + age
}
}
//===========================================================================================================
// FUNCTION: main
//===========================================================================================================
fun main() {
//CALL METHOD.
var person = Person(20)
var newAge = person.addAge(10) //Normal call
newAge = person addAge 10 //Infix call
//DISPLAY RESULT.
print(newAge)
}