Kotlin is a JVM language developed by Jetbrains. Its version 1.0 (production ready) was released at the beginning of the year and made some buzz within the android community. This session proposes to discover this language, which takes up some aspects of groovy or scala, and that is very close to swift in syntax and concepts. We will see how Kotlin boosts the productivity of Java & Android application development and how well it accompanies reactive development.
12. How K can help
you ?
- Conciseness
- Null Safety & Immutability protection
- Static Typing & Smart Casts
- Open programming styles (lambdas, high order functions …)
- Java interop
13. What’s
Kotlin ?
- Fully open source (built by Jetbrains)
- Run on Java 6+
- Static typing & type inference
- Modern language features
- 1st grade tooling
14. What’s inside
Kotlin ?
- String templates
- Properties
- Lambdas
- Data class
- Smart cast
- Null safety
- Lazy property
- Default values for function
parameters
- Extension Functions
- No more ;
- Single-expression
functions
- When expression
- let, apply, use, with
- Collections
- Android Extensions Plugin
15. Compare with
Same conciseness and expressive code, but
Kotlin static typing and null-safety make a big
difference.
"Some people say Kotlin has 80% the power of
Scala, with 20% of the features" *
"Kotlin is a software engineering language in
contrast to Scala which is a computing science
language." *
Swift and Kotlin are VERY similar. Swift is LLVM
based and has C interop while Kotlin is JVM based
and has Java interop.
* Quotes from Kotlin:TheYing andYang of Programming Languages
16. Use Cases
Source : poll on Kotlin Slack (early 2016)https://goo.gl/HIrmC9 @sdeleuze
29. 29
Typing & Inference
val a: Int = 1
val b = 1 // `Int` type is inferred
var x = 5 // `Int` type is inferred
x += 1
Infered values
Mutable values
val : constant value - IMMUTABLE
var : variable value - MUTABLE
USE VAL AS MUCH AS POSSIBLE !
30. 30
Safety with Optionals
var stringA: String = "foo"
stringA = null //Compilation error - stringA is a String (non optional)
var stringB: String? = "bar" // stringB is an Optional String
stringB = null //ok
Optional value
31. 31
Late initialization, Lazy, Delegates …
// set length default value manually
val length = if (stringB != null) stringB.length else -1
//or with the Elvis operator
val length = stringB?.length ?: -1
DefaultValue & Elvis Operator
val length = stringB.length // Compilation error - stringB can be null !
// use ? the safe call operator
val length = stringB?.length //Value or null - length is type Int?
val length = stringB!!.length //Value or explicit throw NPE - length is type Int
Safe call with ?. or Explicit call with !!.
33. 33
Class
class User (
var userName: String,
var firstName: String,
var lastName: String,
var location: Point? = null
)
POJO +
- Getter
- Setter
- Constructors
34. 34
Data Class
data class User (
var userName: String,
var firstName: String,
var lastName: String,
var location: Point? = null
)
POJO +
- Getter
- Setter
- Constructors
- toString
- hashcode
- equals
- copy
36. 36
Properties
// readonly property
val isEmpty: Boolean
get() = this.size == 0
Properties can be declared in constructor or in class
You can also handle getter & setter
// customer getter & setter
var stringRepresentation: String
get() = this.toString()
set(value) {
setDataFromString(value) // parses the string and assigns values to other properties
}
class ApiKey(var weatherKey: String, var geocodeKey: String){
var debug : Boolean = false
}
37. 37
Object Component
// singleton
object Resource {
val name = "Name"
}
println(" my resource is : ${Resource.name}")
class StringCalculator{
// class helper
companion object{
val operators = arrayOf("+","-","x","/")
}
}
println(" my operators are : ${StringCalculator.operators}")
Singleton Class
Companion Object
38. 38
Example
data class User(val name: String = "", val age: Int = 0)
val jack = User(name = "Jack", age = 1)
val anotherJack = jack.copy(age = 2)
json class
data class usage
39. 39
When
when (s) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // Note the block
print("x is neither 1 nor 2")
}
}
Flow Control (replace your old if blocks)
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
Pattern Matching
in <range> ->
is <type> ->
expression ->
when (s) {
is String -> print("s is a string")
else -> print("s is not a string")
}
41. 41
Functions
fun reformat(str: String,
normalizeCase: Boolean = true,
upperCaseFirstLetter: Boolean = true,
wordSeparator: Char = ' '): String {
}
Named Parameters & default values
reformat(str, true, true, '_') // old way to call
reformat(str, wordSeparator = '_') // using default values & named params
fun String.hello(): String = "Hello " + this
val hi = "Arnaud !".hello()
println("$hi") // Hello Arnaud !
Extension
42. 42
Lambdas
val fab = findViewById(R.id.fab) as FloatingActionButton
fab.setOnClickListener { view -> popLocationDialog(view) }
A lambda expression or an anonymous function is a “function literal”, i.e. a
function that is not declared, but passed immediately as an expression
- A lambda expression is always surrounded by curly braces,
- Its parameters (if any) are declared before -> (parameter types may be omitted),
- The body goes after -> (when present).
numberString.split("n").flatMap { it.split(separator) }
.map(Integer::parseInt)
.map(::checkPositiveNumber)
.filter { it <= 1000 }
.sum()
43. 43
Destructuring Data
fun extractDelimiter(input: String): Pair<String, String> = …
val (separator, numberString) = extractDelimiter(input)
data class User(var name : String,var age : Int)
val toto = User("toto",42)
val (name,age) = toto
Returning two values with Pair
Destructured values with data classes
44. 44
Collections
// immutable list
val list = listOf("a", "b", "c","aa")
list.filter { it.startsWith("a") }
// immutable map
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
for ((k, v) in map) {
println("$k -> $v")
}
// mutable map
val map2 = HashMap<String,String>()
// direct map access
map2["a"] = "my value"
println(map2["a"])
// range
for (i in 1..100) { //... }
45. 45
InterOp
object UserSingleton{
fun stringify(user : User) : String{
val (name,age) = user
return "[name=$name][age=$age]"
}
}
fun WhatIsyourAge(user : User){
println("Your age is ${user.age}")
}
data class User (val name: String, val age : Int){
companion object{
fun sayHello(user : User){
println("Hello ${user.name}")
}
}
}
User u = new User("toto",42);
User.Companion.sayHello(u);
UserUtilsKt.WhatIsyourAge(u);
System.out.println("stringify : "+UserSingleton.INSTANCE.stringify(u));
Kotlin code
Calling Kotlin from Java
60. 60
Our feedback
with K
- Easy to start small & grow (no big bang)
- Tool support is very good
- Great feedback about the language itself
- Stable in production !
- Magical conversion … but take care
- Hard to come back to java …
61. 61
IF YOU DON'T LOOK AT
JAVA AND THINK, "THIS
COULD BE BETTER", DON'T
SWITCH.
@RunChristinaRun