5 สิ่งแตกต่าง ที่ Kotlin มีแต่ Java ไม่มี

Android Nov 28, 2022

หลังจากที่คราวที่แล้วเราได้ยก 5 สิ่งแตกต่าง ที่ Kotlin ดีกว่า Java ในฉบับของดีครับน้อน ๆ ไปแล้ว ได้รับเสียงตอบรับที่ดีมาก ๆ และมีคนโวยวายว่า ทำไมมีแค่นี้เอง อ่ะเลยมีภาคสองไปเลยจ้า ในฉบับที่ขิงคนใช้ Java ได้เลยว่า ว้ายแกไม่มีหล่ะสิยัย Java

ใครพลาดบล็อกชุดนี้ตอนแรกอย่าลืมไปอ่านที่บล็อกนี้ได้เลยจ้า

5 สิ่งแตกต่าง ที่ Kotlin ดีกว่า Java (ของดีครับน้อนๆ)
แน่นอนว่าเราเป็น Android Kotlin Developer มานานพอสมควรแล้ว และพบว่าการเขียน Kotlin นั้นทำให้ชีวิตนักพัฒนาดีขึ้นมาก ทำงานได้อย่างมีความสุขมากขึ้น

1) null safety: กันแอพบึ้ม เพราะค่าเป็น null

ปัญหาที่นักพัฒนาแอพพลิเคชั่นแอนดรอยด์ด้วยภาษา Java (หยุดหายใจแปป) มักจะเจอกันบ่อย ๆ คือ แอพแคลชเมื่อมีอะไรสักอย่างเป็น null ซึ่งเวลาที่เราบิ้วแอพ เราจะเจอ error นี้กันบ่อยมาก มีชื่อว่า NullPointerException

เช่น เราให้ name เป็นตัวแปร String เนอะ แล้วรับค่ามาจากหลังบ้าน วันดีคืนร้าย server ส่งมาเป็น null ซะอย่างงั้น ซึ่งในภาษา Java มันไม่มี null safety เลยทำให้แอพของเราบึ้ม

การจัดการ null safety สำหรับภาษา Kotlin ในหลาย ๆ รูปแบบต่าง ๆ

  • จากเคสตัวอย่าง model class ที่เป็น data class ที่มาจาก response จากหลังบ้าน เรามักจะสร้างตัวแปรให้มัน Nullable ได้ โดยการใส่ ? หลังประเภทของตัวแปรนั้น ๆ พร้อมกับ set ค่าเป็น null ด้วยเลย เผื่อหลังบ้านไม่ส่งค่ามา แอพจะได้ไม่บึ้ม เช่น val name: String? = null
  • ตรวจสอบค่า null ก่อนนำไปใช้งานต่อทุกครั้ง เช่น
if (name != null) {
    println(name)
}
  • จากที่เราอาจจะ check ว่า name มันไม่เป็น null ไหม ด้วย name != null เราอาจจะใช้ name?.let{} แบบนี้ได้เหมือนกันนะ มันมีความหมายคือ name != null แล้วทำอะไรต่อนั่นแหละ
name?.let {
    println(name)
}
  • ใส่ safe call ?. สำหรับการเรียกตัวแปรเป็นแบบ chain เมื่อตัวแปรตรงไหนมีค่า null จะทำให้ค่าก้อนนี้เป็น null ทันที เช่น
val name = person?.department?.head?.name
  • ใช้ not-null assertion operator หรือ !! ข้อควรระวังคือ ถ้าใช้กับตัวแปรที่เป็น Nullable เอ้าแตกหนึ่งจ้า
val name = person?.department?.head!!.name
  • ใช้ elvis operator ว่าถ้าค่ามันเป็น null เราจะจัดการกับมันยังไงต่อ
val name = person?.department?.head?.name ?: ""

แน่นอนอันนี้เป็นตัวอย่างที่เราพบกันได้บ่อยเนอะ

สามารถอ่าน document เรื่อง null safety เพื่มเติมได้ที่นี่เลย

Null safety | Kotlin

2) Lambdas and Higher-order Functions: ของดีที่ใคร ๆ ก็ชอบ

เรียกได้ว่าเจ้า Lambdas และ Higher-order Functions เป็นสิ่งนึงที่ตกคนที่เคยเขียน Java มารัก Kotlin ได้ไม่ยากเลย มาดูกันเลยดีกว่า

Lambdas

การประกาศ function ใน Kotlin หน้าตาจะเป็นแบบนี้เนอะ เช่น function checkLengthEqual() ข้างในจะ compare ความยาวของ String 2 ตัวเนอะ ถ้าเท่ากันก็ return true ไป

fun checkLengthEqual(a: String, b: String): Boolean { 
   return a.length == b.length
}

ถ้าเราเขียน function นี้ให้สั้นกว่านี้ ก็จะเป็นแบบนี้เนอะ

fun checkLengthEqual(a: String, b: String): Boolean = a.length == b.length

Lambda Expression เป็นการเขียน function แบบย่อแหละ โดยการใส่แค่ type ของ parameter นั้น ๆ อันนี้เป็นแบบ Function type variable นะ สังเกตที่มันจะเป็นตัวแปร val ไม่ใช่ fun นะ

val checkLengthEqual: (String, String) -> Boolean = { a, b -> a.length == b.length }

จริง ๆ รูปเต็มของ Lambda จะหน้าตาประมาณนี้เนอะ

val checkLengthEqual: (String, String) -> Boolean = { a: String, b: String -> 
    a.length == b.length
} 

แล้วยังสามารถเขียนได้ย่อกว่านี้อีก

val checkLengthEqual = { a: String, b: String -> a.length == b.length }

ข้อดี คือ ถ้ามันมี parameter ตัวเดียว สามารถใช้ it แทนเจ้า parameter ไปได้เลยจ้า เช่น เราต้องการ check ว่า user คนนี้ เขาพิมพ์เกิน 20 ตัวอักษรหรือไม่

val checkMinTextCount: (String) -> Boolean = { it.length == 20 }

และอีกข้อนึง ถ้าตัวแปรไหนที่ไม่ได้ใช้งาน สามารถใช้ _ ละไปได้เลยจ้า เช่น ถ้า editText มันถูก focus อยู่ ให้แสดง keyboard ขึ้นมาเลยจ้า

binding.editText {
    setOnFocusChanged { _, hasFocus ->
        if (hasFocus) showKeyboard()
    }
}

Higher-order Functions

คือ function ที่รับ parameter ที่เป็น function เข้ามา หรือ return เป็น function ออกไป

แล้ว parameter ที่เป็น function เข้ามา คืออะไรนะ?

มันคือ Function types นั่นเอง โดยมาเป็นชุดครอบครัวบาบิก้อน ก็คือเจ้า () -> Unit นั่นเอง มันเป็น function parameter ซึ่งเจ้า () เป็นส่วน input อาจจะไม่มี หรือมีก็ได้ และเจ้า Unit ก็คือ callback เช่น กดปุ่ม OK แล้วทำไรต่อ แต่ละที่จะมีการทำงานตรงนี้ต่างกัน แต่ view เหมือนกันอะเนอะ

เช่น (Int) -> Unit ในที่นี้ input เป็น Int คือการนำค่า Int ไปทำอะไรสักอย่างใน function นั้น สมมุติว่าเป็น fun showBalance(onPrint: (Int) -> Unit) นำค่า Int ที่ได้ไปทำอะไรสักอย่างนึง

fun showBalance(onPrint: (Int) -> Unit) {
    val balance = getBalance()
    onPrint(balance)
}

การนำ showBalance ไปใช้งานก็จะเป็นประมาณนี้

showBalance { balance ->
    currentBalance(balance)
}

นอกจาก จะเป็นพวก Int, String หรืออะไรพวกนี้แล้ว ยังเป็นน้อนก้อน data model ต่างๆได้ด้วยนะ สมมุติว่าเป็น fun getProfile(callback: (Profile) -> Unit

สามารถอ่าน document เรื่อง Lambdas และ Higher-order Functions เพื่มเติมได้ที่นี่เลย

High-order functions and lambdas | Kotlin

3) Scoping Function: ผองเพื่อนของ let, with, apply, also

อีกหนึ่งความสะดวกของชาว Android Kotlin Developer คงหนีไม่พ้น การใช้งานผองเพื่อนเหล่านี้ let, with, apply, also ในโค้ดของเรา ในการจัดระเบียบโค้ดให้อ่านง่าย และใช้งานต่อได้ง่ายด้วยเช่นกัน

แล้วแต่ละตัวคืออะไรกันนะ มาดูไปพร้อมกันเลยจ้า

  • let ก่อนหน้านี้เราจะใช้ในการ check condition with not null ไปแล้ว เราจะใช้ในการ invoke 1 function หรือ หลาย ๆ function ก็ได้ ที่มี result ที่มัน chain กันอยู่ ตัวอย่างหยิบมาจากใน document เนอะ คือเรามี mutableList ของ numbers แล้วทำการ map ความยาวของแต่ละคำ เพื่อ check ว่ามีความยาวมากกว่า 3 หรือไม่ ให้ print ความยาวออกมา
val numbers = mutableListOf("one", "two", "three", "four", "five")
val resultList = numbers.map { it.length }.filter { it > 3 }
println(resultList)

ถ้าเราต้องการให้หลังจากนี้ทำอะไรต่อ ก็สามารถใช้ let เพื่อ chain เช่น พอเราได้ list อันนี้เสร็จแล้ว เอาค่าในนั้นทุกตัวมาบวกกันหน่อยนะ

var count = 0

val numbers = mutableListOf("one", "two", "three", "four", "five")
numbers.map { it.length }.filter { it > 3 }.let { 
    println(it)
    // and more function calls if needed
    it.forEach { i ->
        count += i
    }
    println(count)
}
  • with ใช้ในการจับระเบียบโค้ดเหมือนกัน โดยมันคือ context object ที่ส่งผ่าน argument แต่ข้างในมันจะเป็น lambda

ที่ใช้บ่อย ๆ ก็คือเอามา binding view แล้วก็ใช้กับพวก ViewModel ด้วยนะ

with(binding) {
    button.setOnClickListener {}
    textView.text = "hello"
    editText.hint = "name"
}
  • apply อันนี้เราใช้บ่อยมาก ใช้ในการจัดระเบียบโค้ดให้มันดูเรียบร้อยขึ้น ในการ set attribute ต่างๆ ของ View อะไรงี้ โดยมี object reference ด้านในเป็น this การใช้ไม่ต้องเรียกมันมานะ ใส่ไปได้แบบนี้เลย
button.apply {
    text = "Login"
    background = ContextCompat.getDrawable(context, R.drawable.bg_round_orange)
    setOnClickListener {}
}
  • also เหมือนกับ apply แต่เราจะต้องใช้ it ที่แทน object ตัวนั้นที่เราอ้างอิง
button.also {
    it.text = "Login"
    it.background = ContextCompat.getDrawable(context, R.drawable.bg_round_orange)
    it.setOnClickListener {}
}

ปล. จริง ๆ มี run ด้วย แต่เราไม่ค่อยได้ใช้ เลยไม่ได้อธิบายในที่นี่เนอะ

สามารถอ่าน document เกี่ยวกับ Scoping Function ได้ที่นี่

Scope functions | Kotlin

4) Coroutines: ของดีย์ในการจัดการ Thread

เวลาที่เราเขียนแอพเชื่อมต่อกับ API Service ต่าง ๆ เราจะต้องใช้ตัวจัดการการทำงานแบบ asynchronous ต่าง ๆ ที่ใช้กันก็จะมี RxJava ใช่ม่ะ แต่ในภาษา Kotlin มีสิ่งนี้มาให้เราแล้ว นั่นก็คือ Coroutines

ถ้าเราเขียนแอพ Architecture แบบ MVVM (Model View ViewModel) เราจะใช้ Coroutines กับViewModel, LiveData, Repository, และ Room กันเนอะ

โดยเจ้า Coroutine นั้นมาตอน Kotlin 1.3 ซึ่งเขา release ในวันที่ 29 October 2018 เป็น concurrency design pattern ที่ใช้ใน Android ในการ executes พวก asynchronous มาช่วยแก้ปัญหา 2 อย่าง คือ

  • Manage long-running tasks เป็นจัดการงานที่ทำมาอย่างยาวนาน ซึ่งทำให้ main thread ถูกล็อก และทำให้แอพเราค้าง โดยเรามักจะใช้ suspend หน้าชื่อ function เพื่อบอกว่าให้หยุดการ execute ชั่วคราวสำหรับ current Coroutine หรือสามารถสร้าง Coroutine ได้โดยใช้ launch หรือ async ที่ใช้คู่กับ await ก็ได้
  • Use Coroutine for main-safety ใช้เพื่อความปลอดภัยหลัก ในการเรียก network และ disk operations จาก main thread ใน Kotlin มีให้ใช้ 3 ตัว ก็คือ
    - Dispatchers.Main ใช้ในการเรียก Main Thread
    - Dispatchers.IO อันนี้ทำงานนอก Main Thread เรามักจะใช้เรียกพวก Service API ต่าง ๆ เนอะ
    - Dispatchers.Default อันนี้ก็ทำงานนอก Main Thread เช่นกัน

จริง ๆ เคยเขียนเกี่ยวกับ Coroutines และ MVVM ไปบ้างแล้ว สามารถอ่านต่อได้ที่นี่เลย

สับเปลี่ยนกระบวนท่าจาก MVP ไป MVVM และ Coroutine ยังไงไม่ให้แอพพัง
ในเมื่อหลายๆที่เขาใช้ MVVM กันแล้ว และทีมอื่นก็ด้วย ทำไมเรายังไม่มุ้ปอรหล่ะ!

สามารถอ่าน document ของ Coroutines ได้ที่นี่เลย

Coroutines | Kotlin
Kotlin coroutines on Android | Android Developers

5) Jetpack Compose

อันนี้มาจะแหวกกว่าเพื่อนหน่อย คืองี้นะทุกคน ตามที่ทุกคนรู้กันว่า official support ภาษา kotlin เป็นอันดับหนึ่งใช่ป้ะ ซึ่งหนึ่งใน feature ใหม่ ๆ ที่เป็นแบบใหญ่ ๆ เลย คงหนีไม่พ้น Jetpack Compose หล่ะเนอะ

Jetpack Compose เป็นการสร้าง Android UI อีกวิธีนึง วิธีการจะคล้าย ๆ Flutter มันคือ toolkit สำหรับสร้าง Android UI ด้วยโค้ดแบบ DSL Style เราสามารถเห็นโค้ด UI ที่เราเขียนได้ ถ้าถามว่าเห็นง่ายขนาดไหน ง่ายขนาดที่ไม่ต้องรันแอพแล้วกดดูหน้านั้น ๆ อ่ะ

สามารถดูเพิ่มเติมเกี่ยวกับ Jetpack Compose ได้ที่นี่เลย

Android Codelabs Together ตอน Jetpack Compose Basics
กลับมาใน season 2 ของงาน Android Codelabs Together และในที่สุด! ก็ได้ถึงเวลา! ได้ลองทำ! Jetpack Compose ซะที

จริง ๆ แล้ว ของดีของ Kotlin ยังไม่หมดแค่นี้ เพราะยังมีอีกมากมาย

ถ้าใครอยากลองสัมผัส เชิญชวนได้ที่คอร์ส Getting Started with Kotlin นี้เลย เนื้อหา official จากทีม Android สอนโดยคุณเอก Android GDE เชียวนะ

แต่ทางเราได้ข่าวมาว่า มีคนอยากได้เสื้อ Kotlin สวย ๆ นี้ไปใส่ใช่ไหมหล่า แต่ไม่ทันรอบที่แล้ว

บอกเลยว่าคอร์สนี้เรียนฟรี เรียนจบครบตามเกณฑ์แล้วได้ของฟรีด้วยน้า

ตัวกิจกรรมจะมีถึงวันที่ 16 ธันวาคม 2565 ของแจกแบบ first come first serve ช้าหมดอดน้า

📝 กติกาการรับของรางวัล

  1. เรียนคอร์ส Getting Started with Kotlin จบ 100%
    https://to.skooldio.com/kotlin-online-course-free
  2. ทำแบบทดสอบวัดความรู้เรื่อง Kotlin ได้คะแนน 225 คะแนนขึ้นไป
    https://to.skooldio.com/kotlin-skill-score
  3. ลงทะเบียนรับเพื่อรับของรางวัลจากทาง Google ได้ ที่นี่เลย
    https://forms.gle/59WReyXy1JnXXexe8

คนที่มาจากเพจเราหรือเจอบล็อกเรา อย่าลืมวงเล็บ MikkiPastel ไว้หลังชื่อแบบนี้ด้วยนะ เพราะรอบนี้จะมีสติ๊กเกอร์จากเพจของเราด้วยน้า

อย่าลืมวงเล็บ MikkiPastel ไว้หลังชื่อแบบนี้ด้วยนะ เพราะรอบนี้จะมีสติ๊กเกอร์จากเพจของเราด้วยน้า ตัวอย่างจ้า https://forms.gle/59WReyXy1JnXXexe8

ตัวอย่าง sticker ที่แจกในรอบนี้ เป็นแผ่นขนาด A5 ที่ยังไม่ final จ้า


สามารถ support ค่ากาแฟเจ้าของบล็อกได้ที่ปุ่มแดงส้มสุดน่ารักที่มุมซ้ายล่าง หรือกดปุ่มตรงนี้ก็ได้จ้า

Buy Me a Coffee at ko-fi.com

ช่องทาง Twitter ติดตามข่าวสารแบบไวๆ

ติดตามข่าวสารและบทความใหม่ๆได้ที่

อย่าลืมกด like กด share บทความกันด้วยนะคะ :)

Posted by MikkiPastel on Sunday, 10 December 2017

ช่องทางใหม่ ติดตามทุกๆสตรีมของเราได้ที่

Twitch
Twitch is the world’s leading video platform and community for gamers.
https://www.twitch.tv/mikkipastel

Subscribe ช่อง YouTube ของเราได้ที่

mikkicoding
Android Developer & Content Creator
https://www.youtube.com/c/mikkicoding

download แอพอ่านบล็อกใหม่ของเราได้ที่นี่

MikkiPastel - Apps on Google Play
First application from “MikkiPastel” on play store beta feature- read blog from https://www.mikkipastel.com by this application- read blog content by chrome custom tab- update or refresh new content by pull to refresh- share content to social network
https://play.google.com/store/apps/details?id=com.mikkipastel.blog

Tags

Minseo Chayabanjonglerd

I am a full-time Android Developer and part-time contributor with developer community and web3 world, who believe people have hard skills and soft skills to up-skill to da moon.