Sunday 2 July 2017

Kotlin - Extension Vs Infix

Extension:
Kotlin, similar to Objective C (Categories) & C# Extension methods, here kotlin provides the ability to extend a class with new functionality without inheriting the class i.e. by using the Decorator design pattern. This is done via special declarations called extensions. Kotlin supports both extension functions and extension properties.

Infix Function:
In Simple, All Extension functions are not Infix, but every Infix method must to be extension function.

Criteria: 
0. Mandatory to have a params to the function,
1. Function does not accept more than one params.

// Definition: Extension function, here we have extending the checkCastMyVote from the String Class (In-Built Class).
// Here the function is used as an expression.

fun String.checkCastMyVote(name: String, age: Int) =
        if (age >= ELIGIBLE_YEAR) {
            "$this $name your age is $age, you are eligible to cast your vote"
        } else if (age in 0..17) {
            "$this $name you need to wait for ${ELIGIBLE_YEAR.minus(age)} more year(s)"
        } else {
            "$this $name, please provide the valid birth year (Given: $age)"
        }

// Calling a Extension Function: 
println("Mr.".checkCastMyVote("Ragavan", 23))  // Passing a params
println("Mr.".checkCastMyVote(age = 42, name = "Rajeevan"))  // Named functions


// Infix function definition
infix fun Int.getAge(yob: Int) =
        if (yob > 0) {
            this.minus(yob)
        } else {
            yob
        }

// Infix function call (no need to use dot or typical function calling syntax)
val CURRENT_YEAR=2017
var YEAR_OF_BIRTH=1988
var age = CURRENT_YEAR getAge YEAR_OF_BIRTH

Also, we can also apply & access this both extension and infix function to the user defined classes as well.

// Defining the class
class Guru {
    var name: String = ""
    fun isPassed(totalMark: Int) = if (totalMark > 35) "Passed" else "Failed"
}

// Defining the infix function.
infix fun Guru.isScholarshipEligibleMessage(totalMark: Int) =
        when (totalMark) {
            in 0..34 -> "No scholarship available for ${this.name} "
            in 35..50 ->
                "${this.name} Avail 50% Scholarship of amount"
            in 51..80 -> "${this.name} Avail 70% of Scholarship amount"
            in 81..100 -> "${this.name} Avail 85% of Scholarship amount"
            else -> "${this.name} Total Mark is invalid"
        }


// Calling the method
 var guru = Guru()
    guru.name = "Rajeev Menon"
    var totalMarks = 0 //38 //79 //85
    println("${guru.name} is ${guru.isPassed(totalMarks)}")
    println(guru isScholarshipEligibleMessage totalMarks)