Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin Discovery

Kotlin Discovery

What make Kotlin different.

Moncef AOUDIA

February 18, 2019
Tweet

Other Decks in Programming

Transcript

  1. Plan 1. Kotlin 2. The good 3. The bad 4.

    Android Kotlin 5. Spring Kotlin 6. Questions 3
  2. Null safety 8 var x: String = "hello" x =

    null // Null can not be a value of a non-null type String val x = "Hello" val y: String? = null println(x.length) // print 5 println(y?.length) // print null var y: String? = "world" y = null // ok, no error print(y) // print null
  3. Extensions functions 9 fun Int.isEvenOrOdd() { if (this % 2

    == 0) println("$this is even") else println("$this is odd") } fun main() { val num:Int? = 10 num?.isEvenOrOdd() }
  4. Higher-order function 10 fun <T, R> Collection<T>.fold( initial: R, combine:

    (acc: R, nextElement: T) -> R ): R { var accumulator: R = initial for (element: T in this) { accumulator = combine(accumulator, element) } return accumulator } val items = listOf(1, 2, 3, 4, 5) items.fold(0, { acc: Int, i: Int -> print("acc = $acc, i = $i, ") val result = acc + i println("result = $result") result })
  5. Higher-order function 11 // Parameter types in a lambda are

    optional if they can be inferred: val joinedToString = items.fold("Elements:", { acc, i -> acc + " " + i }) // Function references can also be used for higher-order function calls: val product = items.fold(1, Int::times)
  6. Sealed class 12 sealed class Opt { class Add(val value:

    Int) : Opt() class Sub(val value: Int) : Opt() class Mult(val value: Int) : Opt() class Div(val value: Int) : Opt() object Inc(val value: Int) : Opt() object Dec(val value: Int) : Opt() } fun calc(x: Int, op: Opt) = when (op) { is Opt.Add -> x + op.value is Opt.Sub -> x - op.value is Opt.Mult -> x * op.value is Opt.Div -> x / op.value Opt.Inc -> x + 1 Opt.Dec -> x - 1 // the `else` clause is not required because we've covered all the cases }
  7. Let 14 /** * Calls the specified function [block] with

    `this` value as its argument and returns its result. */ public inline fun <T, R> T.let(block: (T) -> R): R = block(this) val x = "Hello" val y = "World" val sb = StringBuilder() val letResult = sb.let{ it.append(x) it.append(y) "Let" } println(sb.toString()) //HelloWorld println(letResult) //Let val x = "Hello" val y = "World" var sb: StringBuilder? = null val letResult = sb?.let{ it.append(x) it.append(y) "Let" } println(letResult) //null sb = StringBuilder() sb.append(x) println(sb.toString()) //Hello
  8. Apply 15 /** * Calls the specified function [block] with

    `this` value as its receiver and returns `this` value. */ public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this } val lille = City() lille.name = "Lille" lille.surface = 3_951 lille.population = 233_897 val lille = City().apply { name = "Lille" surface = 3_951 population = 233_897 }
  9. Also 16 /** * Calls the specified function [block] with

    `this` value as its argument and returns `this` value. */ @SinceKotlin("1.1") public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this } // transforming data from database with intermediary variable val user = db.getUser(id = 0) log.debug(user.toString()) user.map { /** other stuff */ } // use 'also' to stay in the method chains val user = db.getUser(id = 0) .also { log.debug(it.toString())} .map { /** other stuff */ }
  10. With 17 /** * Calls the specified function [block] with

    the given [receiver] as its receiver and returns its result. */ public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block() // using old way val surface = lille.surface val population = lille.population val density = population/surface // using 'with' to avoid repetitive references to identifier val density = with(lille) { population/surface }
  11. Run 18 /** * Calls the specified function [block] with

    `this` value as its receiver and returns its result. */ public inline fun <T, R> T.run(block: T.() -> R): R = block() /** * Calls the specified function block and returns its result. */ public inline fun <T, R> run(block: () -> R): R = block() val person: Person = Person(...) val personRepository: PersonRepository = personRepository() personRepository.delete(person) fun printName(person: Person) = person.run { println(person.name) } val isDeleted: Boolean = run { val person: Person = Person(...) val personRepository: PersonRepository = personRepository() personRepository.delete(person) } fun printName(person: Person) = person.run { println(name) }
  12. Coroutines 20 // Create a custom CoroutineScope override val coroutineContext:

    CoroutineContext get() = Dispatchers.Main + job private lateinit var job: Job job = Job() launch(Dispatchers.Main) { // Suspend the execution of Coroutine until doLogin finish val user = withContext(Dispatchers.IO) { userService.doLogin(username, password) } // Get currentFriends without suspending the Coroutine val currentFriends = async(Dispatchers.IO) { userService.requestCurrentFriends(user) } // Get suggestedFriends without suspending the Coroutine val suggestedFriends = async(Dispatchers.IO) { userService.requestSuggestedFriends(user) } val finalUser = user.copy(friends = currentFriends.await() + suggestedFriends.await()) } // Wait for the execution of the Job job.join() job.cancel()
  13. Heritage 22 class MyClass { } class SubClass : MyClass

    { /* /* this type is final, so it can be inherited from */ } open class MyClass { } class SubClass : MyClass { /* it works */ }
  14. Data class 23 data class MyDataClass(val p: Int = 19)

    { } class SubClass : MyDataClass(p) { /* this type is final, so it can be inherited from */ } open class MyClass(val x: Int = 19) { } data class MyDataClass(val y: Int) : MyClass() { /* it works */ }
  15. Class constructor 24 // primary constructor class PersonA(val firstName: String,

    val lastName: String) { } // regular constructor class PersonB { val firstName: String val lastName: String constructor(firstName: String, lastName: String){ this.firstName = firstName this.lastName = lastName } } class Student(val firstName: String, val lastName: String, val studentId: String) : Person(firstName,lastName) { }
  16. Class companion 25 class MyClass { companion object { @JvmStatic

    fun myStaticMethod(/*...*/) { /*...*/ } } }
  17. Type conversion 26 val x: Int = 19 val y:

    Long = x // Type mismatch: inferred type is Int but Long was expected fun main() { val x: Int = 128 val y: Byte = x.toByte() val z: Int = y.toInt() print("(x = $x, y = $y, z = $z)") } Output:(x = 128, y = -128, z = -128) val x: Int = 19 val y: Long = x.toLong() // Ok
  18. Keywords 27 Hard Keywords Soft Keywords Modifier Keywords Other Keywords

    package, as, typealias, class, this, super, val, var, fun, for, null, true, false, is, in, throw, return, break, continue, object, if, try, else, while, do, when, interface, yield, typeof by, catch, constructor delegate, dynamic, field, file, finally, get, import, init, param, property, receiver, set setparam, where actual, abstract, annotation, companion, const, crossinline, data, enum, expect, external, final, infix, inline, inner, internal, lateinit, noinline, open, operator, out, override, private, protected, public, field, it, +, -, *, /, %, =, +=, -=, *=, /=, %=, ++, --, &&, ||, ! - , and, or, not, ==, !=, ===, !==, <, >, <=, >=, [, ], !!, ?., ?:, ::, .., :, ?, ->, @, ;, $, _
  19. 28

  20. Kotlin Android It makes Android development much easier It’s seamlessly

    integrated with Android Studio If you’re an Android developer, you need to recycle There are well-known companies that already use it in production Companies are starting to ask for it on their job offers 29
  21. Gradle Kotlin DSL 30 import org.jetbrains.kotlin.config.KotlinCompilerVersion plugins { id("com.android.application") id("kotlin-android")

    } android { compileSdkVersion(28) buildToolsVersion = "28.0.1" defaultConfig { applicationId = "com.zenika.bbl" ... } ... } dependencies { implementation(kotlin("stdlib-jdk7", KotlinCompilerVersion.VERSION)) testImplementation("junit:junit:4.12") }
  22. Kotlin Android Extensions 31 // Using R.layout.activity_main from the 'main'

    source set import kotlinx.android.synthetic.main.activity_main.* class MyActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Instead of findViewById<TextView>(R.id.textView) textView.setText("Hello, world!") } }
  23. 33

  24. Kofu DSL 34 val app = webApplication { beans {

    bean<SampleService>() bean<SampleHandler>() } server { port = if (profiles.contains("test")) 8181 else 8080 router { val handler = ref<SampleHandler>() GET("/", handler::hello) GET("/api", handler::json) } codecs { string() jackson() } } }
  25. Kofu DSL 35 data class Sample(val message: String) class SampleService

    { fun generateMessage() = "Hello world!" } class SampleHandler(private val sampleService: SampleService) { fun hello(request: ServerRequest)= ok().syncBody(sampleService.generateMessage()) fun json(request: ServerRequest) = ok().syncBody(Sample(sampleService.generateMessage())) } fun main() { app.run() }
  26. Kotlin Script Templates 36 import io.spring.demo.* """ ${include("header")} <h1>${i18n("title")}</h1> <ul>

    ${users.joinToLine{ "<li>${i18n("user")} ${it.firstname} ${it.lastname}</li>" }} </ul> ${include("footer")} """
  27. Sources • https://antonioleiva.com/reasons-kotlin-android/ • https://techbeacon.com/why-you-should-use-kotlin-android-development • https://dzone.com/articles/why-kotlin-is-the-future-of-android-app-developmen • https://developer.android.com/kotlin/faq •

    https://dzone.com/articles/what-are-the-biggest-advantages-of-kotlin-over-jav • https://hackernoon.com/why-we-choose-kotlin-for-creating-android-apps-46030b10d19c • https://code.tutsplus.com/articles/java-vs-kotlin-should-you-be-using-kotlin-for-android-development--cm s-27846 • https://github.com/MindorksOpenSource/from-java-to-kotlin • https://codelabs.developers.google.com/codelabs/kotlin-coroutines/ • https://dev.to/martinhaeusler/kotlin---the-good-the-bad-and-the-ugly-3jfo • https://kukuruku.co/post/why-kotlin-sucks/ • https://allegro.tech/2018/05/From-Java-to-Kotlin-and-Back-Again.html • https://blog.dripstat.com/kotlin-in-production-the-good-the-bad-and-the-ugly-2/ 39
  28. Sources • https://kotlinlang.org/ • https://proandroiddev.com/the-tldr-on-kotlins-let-apply-also-with-and-run-functions-6253f06d152b • https://medium.com/@elye.project/mastering-kotlin-standard-functions-run-with-let-also-and-apply-9cd33 4b0ef84 • https://antonioleiva.com/coroutines/

    • https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0 • https://romannurik.github.io/SlidesCodeHighlighter/ • http://kotlinlang.org/docs/reference/keyword-reference.html • https://proandroiddev.com/kotlin-sealed-classes-enums-with-swag-d3c4b799bcd4 • https://antonioleiva.com/sealed-classes-kotlin/ • https://proandroiddev.com/migrating-android-app-to-gradle-kotlin-dsl-1-0-c903760275a5 • https://github.com/spring-projects/spring-fu 40