A programming language
Object Oriented
Functionnal
Designed for the JVM and Android
Works everywhere where Java works
Works with all major Java tools/frameworks
Interoperable with Java
Production-ready
Defining packages
package my.demo
import java.util.*
// ...
Defining functions
Function having two Int parameters with Int return type:
fun sum(a: Int, b: Int): Int {
return a + b
}
Function with an expression body and inferred return type:
fun sum(a: Int, b: Int) = a + b
Defining functions
Function returning no meaningful value:
fun printSum(a: Int, b: Int): Unit {
print(a + b)
}
Unit return type can be omitted:
fun printSum(a: Int, b: Int) {
print(a + b)
}
Expressions
This statement :
fun max(a: Int, b: Int): Int {
if (a > b)
return a
else
return b
}
can be re-writen in a one-liner, using if as an expression
fun max(a: Int, b: Int) = if (a > b) a else b
Defining variables
Assign-once (read-only) local variable:
val a: Int = 1
val b = 1 // `Int` type is inferred
val c: Int // Type required when no initializer is provided
c = 1 // definite assignment
Mutable variable:
var x = 5 // `Int` type is inferred
x += 1
String templates
fun example1(a: Any, b: Any) =
"This is some text in which variables ($a, $b) appear."
A POJO with getters, setters, equals(), hashCode(), toString() and copy() in a single line:
data class Customer(val name: String, val email: String, val company: String)
fun bar(i: Int, s: String = "", b: Boolean = true) {}
fun usage() {
// named arguments:
bar(1, b = false)
}
All use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.
A regular variable cannot hold a null reference
var a: String = "abc"
a = null // compilation error
val l = a.length // ok: variable 'a' will never be null
To allow nulls, we can declare a variable as nullable using ?
var b: String? = "abc"
a = null // ok
val l = b.length // error: variable 'b' can be null
Checking for null in conditions
val l = if (b != null) b.length else -1
Safe Calls '?'
val l = b?.length // returns b.length if b is not null, and null otherwise
Elvis operator ?:
val l = b?.length ?: -1
If the expression to the left of ?: is not null, the elvis operator returns it, otherwise it returns the expression to the right
Extend a class without having to inherit from the class or use a Decorator pattern
Collections.sort( myList, myComparator );
fun List.sort( myComparator ) {
Collections.sort(this, myComparator )
}
myList.sort(myComparator)
fun String.toCamelCase() { ... }
"Convert this to camelcase".toCamelCase()
Immutable & Mutable collections
val numbers: MutableList<Int> = mutableListOf(1, 2, 3)
val readOnlyView: List<Int> = numbers
println(numbers) // prints "[1, 2, 3]"
numbers.add(4)
println(readOnlyView) // prints "[1, 2, 3, 4]"
readOnlyView.clear() // -> does not compile
// 'clear' is not in the Immutable interface
val items = listOf(1, 2, 3, 4)
items.first() == 1
items.last() == 4
items.filter { it % 2 == 0 } // returns [2, 4]
// have you seen the Lambda ?
val rwList = mutableListOf(1, 2, 3)
rwList.requireNoNulls() // returns [1, 2, 3]
if (rwList.none { it > 6 }) println("No items above 6")
// prints "No items above 6"
val item = rwList.firstOrNull()
Functions that takes functions as a parameter
fun <T, R> List<T>.map(transform: (T) -> R): List<R> {
val result = arrayListOf<R>()
for (item in this)
result.add(transform(item))
return result
}
val doubled = ints.map { it -> it * 2 } // or : ints.map { it * 2 }
strings.filter { it.length == 5 }.map { it.toUpperCase() }
Less boilerplate code (POJOs)
Say bye-bye to NullPointerExceptions
Works with my favorites frameworks