Introduction

Kotlin is a compiled, statically typed language, which might provide some initial hurdles for people who are used to the interpreted, dynamically typed Python. This document aims to explain a substantial portion of Kotlin's syntax and concepts in terms of how they compare to corresponding concepts in Python..

Kotlin can be compiled for several different platforms. In this document, we assume that the target platform is the Java virtual machine, which grants some extra capabilities - in particular, your code will be compiled to Java bytecode and will therefore be interoperable with the large ecosystem of Java libraries.

Even if you don't know Python, this document should hopefully be a useful introduction to Kotlin, in particular if you are used to other dynamically typed languages. However, if you're coming from a Java background, you're probably better off diving directly into the excellent official docs (from which this doc has drawn a lot of inspiration). To some extent, you can try to write Java code and look stuff up whenever what you're trying to do doesn't work - and some IDEs can even automatically convert Java code to Kotlin.

Why switch to Kotlin

Reasons can be:

  • Java is not a modern language.
  • Android only supports a subset of Java 8 features. In a way, Android developers are not able to reap full benefits of Java. In case they require making use of Java, then they will have to stick to Java 7.
  • Java comes with some well-documented language issues like endless try-catch blocks, null-unsafety, NullPointerExceptions and lack of extendability.
  • Java is still a procedural language although it is starting to add lambda expressions and functional interfaces recently.
  • The syntax of Java is very complex and writing longer code can always be prone to more errors and bugs.
  • Java can create issues with Android API design.
  • Do you still need to remember most of the code while you code in Java? It can be creepy and messy sometimes!
  • Java Vs Kotlin
    Hello world
    To get started with writing Kotlin, open the editor and write your first "Hello world" Kotlin code: fun main(args: Array) { print("Hello World") }
    Comments In Kotlin
    /* * This is comment line 1 * * This is comment line 2 * * This is main function. Entry point of the application. * */ fun main(args: Array) { // This is inline comment ... print("Hello World") }
    Declaring variables
    /* * This is main function. Entry point of the application. * */ fun main(args: Array) { var myNumber = 10 // Int var myDecimal = 1.0 // Float var isActive = true // Boolean var myString: String // Mutable String myString = "Hello World" myString = "Another World" val myAnotherString = "My constant string value" // Immutable String // myAnotherString = "some value" // NOT ALLOWED, since it is immutable print(myNumber) }
    Variable scope & Naming

    A variable only exists inside the scope (curly-brace-enclosed block of code; more on that later) in which it has been declared - so a variable that's declared inside a loop only exists in that loop; you can't check its final value after the loop. Variables can be redeclared inside nested scopes - so if there's a parameter x to a function and you create a loop and declare an x inside that loop, the x inside the loop is a different variable than the parameter x.

    Variable names should use lowerCamelCase instead of snake_case.

    In general, identifiers may consist of letters, digits, and underscores, and may not begin with a digit. However, if you are writing code that e.g. autogenerates JSON based on identifiers and you want the JSON key to be a string that does not conform to these rules or that collides with a keyword, you can enclose it in backticks: `I can't believe this is not an error!` is a valid identifier.

    Data Types
    All variables must be initialize at the time of declaration.
  • Boolean -- 1 bit
  • Byte -- 8 bits
  • Char -- 16 bits
  • Short -- 16 bits
  • Int -- 32 bits
  • Long -- 64 bits
  • Float -- 32 bits
  • Double -- 64 bits

  • println(7 / 3) // Prints 2 println(7 / 3.0) // Prints 2.3333333333333335 val x = 3 println(7 / x) // Prints 2 println(7 / x.toDouble()) // Prints 2.3333333333333335
    /* * Explore Data Types in Kotlin * */ fun main(args: Array) { var name: String name = "Kevin" var age: Int = 10 var myAge = 10 var isAlive: Boolean = true var marks: Float = 97.4F var percentage: Double = 90.78 var gender: Char = 'M' print(marks) }
    Kotlin Basics
    /* * This is main function. Entry point of the application. * */ fun main(args: Array) { var personObj = Person() personObj.name = "Steve" print("The name of the person is ${personObj.name}") } class Person { var name: String = "" }
    String Interpolation
    ${ } /* * Explore String Interpolation in Kotlin * */ fun main(args: Array) { var rect = Rectangle() rect.length = 5 rect.breadth = 3 print("The length of the rectangle is ${rect.length} and breadth is ${rect.breadth}. The area is ${rect.length * rect.breadth}") } class Rectangle { var length: Int = 0 var breadth: Int = 0 }
    Ranges
    /* * Explore Ranges * */ fun main(args: Array) { var r1 = 1..5 // This range contains number 1, 2, 3, 4, 5 val r2 = 5 downTo 1 // This range contains number 5, 4, 3, 2, 1 val r3 = 5 downTo 1 step 2 // This range contains number 5, 3, 1 val r4 = 'a'..'z' // This range contains the values from "a", "b", "c" . . . "z" var isPresent = 'c' in r4 var countDown = 10.downTo(1) // This range contains number 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 var moveUp = 1.rangeTo(10) // This range contains number 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
    If...else As Expression
    /* * IF as Expression * */ fun main(args: Array) { val a = 2 val b = 5 var maxValue: Int = if (a > b) { print("a is greater") a } else { print("b is greater") b } println(maxValue) }
    When Expression
    It is the replacement of classical Switch case: /* * WHEN as Expression * */ fun main(args: Array) { val x = 100 val str: String = when (x) { 1 -> "x is 1" 2 -> "x is 2" else -> { "x value is unknown" "x is an alien" } } println(str) }
    For Loop
    /* * FOR Loop * */ fun main(args: Array) { for (i in 1..10) { if (i % 2 == 0) { println(i) } } println() for (i in 10 downTo 0) { if (i % 2 == 0) { println(i) } } }
    While Loop
    /* * WHILE Loop * */ fun main(args: Array) { var i = 0 while (i <= 10) { if (i % 2 == 0) { println(i) } i++ } println() var j = 10 while (j >= 0) { if (j % 2 == 0) { println(j) } j-- } }
    Do While Loop
    /* * DO WHILE Loop * */ fun main(args: Array) { var i = 0 do { if (i % 2 == 0) { println(i) } i++ } while (i <= 10) println() var j = 10 do { if (j % 2 == 0) { println(j) } j-- } while (j >= 0) }
    Break
    /* * BREAK Keyword and Labelled FOR Loop * */ fun main(args: Array) { for (i in 0..4) { println(i) if (i == 2) { break } } println() myLoop@ for (i in 1..3) { for (j in 1..3) { println("$i $j") if (i == 2 && j == 2) break@myLoop } } }
    Continue Keyword
    /* * BREAK Keyword and Labelled FOR Loop * */ fun main(args: Array) { for (i in 0..4) { println(i) if (i == 2) { break } } println() myLoop@ for (i in 1..3) { for (j in 1..3) { println("$i $j") if (i == 2 && j == 2) break@myLoop } } }
    Function Basic
    Functions are declared with the fun keyword. For the parameters, you must declare not only their names, but also their types, and you must declare the type of the value the function is intending to return. The body of the function is usually a block, which is enclosed in curly braces:
    fun happyBirthday(name: String, age: Int): String { return "Happy ${age}th birthday, $name!" } Here, name must be a string, age must be an integer, and the function must return a string. However, you can also make a oneliner function, where the body simply is the expression whose result is to be returned. In that case, the return type is inferred, and an equals sign is used to indicate that it's a oneliner: fun square(number: Int) = number * number (Note that there is no ** operator; non-square exponentiation should be done via Math.pow().) Function names should use lowerCamelCase instead of snake_case.
    Named Parameter
    /* * Named Parameters * */ fun main(args: Array) { var result = findTheVolume(breadth = 2, length = 3) print(result) } fun findTheVolume(length: Int, breadth: Int, height: Int = 10): Int { return length * breadth * height }
    Extension Function
    /* * Extension Functions: EXAMPLE ONE * */ fun main(args: Array) { var student = Studentt() println("Pass status: " + student.hasPassed(57)) println("Scholarship Status: " + student.isScholar(57)) } fun Studentt.isScholar(marks: Int): Boolean { return marks > 95 } class Studentt { // OUR OWN CLASS fun hasPassed(marks: Int): Boolean { return marks > 40 } }
    Infix Function
    /* * INFIX FUNCTIONS * */ fun main(args: Array) { val x: Int = 6 val y: Int = 10 val greaterVal = x findGreaterValue y // x.findGreaterValue(y) println(greaterVal) } infix fun Int.findGreaterValue(other: Int): Int { // INFIX and Extension Func if (this > other) return this else return other } /* * 1. All INFIX Functions are Extension functions * But all Extension functions are not INFIX * 2. INFIX Functions just have ONE PARAMETER * */
    Tailrec Function
    import java.math.BigInteger /* * Tailrec Function : Recursive Functions * -> Prevents Stackoverflow Exception * * Fibonacci Series * 0 1 1 2 3 5 8 13 21 ...... * */ fun main(args: Array) { println(getFibonacciNumber(10000, BigInteger("1"), BigInteger("0"))) } tailrec fun getFibonacciNumber(n: Int, a: BigInteger, b: BigInteger): BigInteger { if (n == 0) return b else return getFibonacciNumber(n - 1, a + b, a) }
    Inheritance
    /* * Inheritance * */ fun main(args: Array) { var dog = Dog() dog.bread = "labra" dog.color = "black" dog.bark() dog.eat() var cat = Cat() cat.age = 7 cat.color = "brown" cat.meow() cat.eat() var animal = Animal() animal.color = "white" animal.eat() } open class Animal { // Super class / Parent class / Base class var color: String = "" fun eat() { println("Eat") } } class Dog : Animal() { // Sub class / Child class / Derived class var bread: String = "" fun bark() { println("Bark") } } class Cat : Animal() { // Sub class / Child class / Derived class var age: Int = -1 fun meow() { println("Meow") } }
    Array
    /* * 1. Arrays * */ fun main(args: Array) { // Elements : 32 0 0 54 0 // Index : 0 1 2 3 4 var myArray = Array(5) { 0 } // Mutable. Fixed Size. myArray[0] = 32 myArray[3] = 54 myArray[1] = 11 for (element in myArray) { // Using individual elements (Objects) println(element) } println() for (index in 0..myArray.size - 1) { println(myArray[index]) } }
    Interface
    /* * INTERFACE * */ fun main(args: Array) { var myButton = MyButton() myButton.onTouch() myButton.onClick() } interface MyInterfaceListener { // You cannot create the instance of interface fun onTouch() // Methods in interface are abstract by default fun onClick() { // Normal methods are public and open by default but NOT FINAL println("MyInterfaceListener: onClick") } } interface MySecondInterface { // You cannot create the instance of interface fun onTouch() { // Normal Method println("MySecondInterface: onTouch") } fun onClick() { // Normal methods are public and open by default but NOT FINAL println("MySecondInterface: onClick") } } class MyButton: MyInterfaceListener, MySecondInterface { override fun onTouch() { super.onClick() super.onClick() } override fun onClick() { super.onTouch() } }
    Reference
    Know Creator