สรุปการเดินทางหนึ่งเดือนกับ Kotlin

Jedsada Tiwongvorakul
20Scoops CNX
Published in
5 min readJul 22, 2017

สำหรับการพัฒนาแอพฯแอนดรอย์ก็คงหนีไม่พ้นที่ต้องใช้ภาษา Java แต่ปัจจุบันก็ได้มีภาษาเกิดขึ้นมาใหม่ขึ้นมาซึ่งถือว่าเป็นกระแสที่ร้อนแรงกันเลยทีเดียวนั่นก็คือเจ้า Kotlin นั่นเอง

ก่อนจะเริ่มศึกษาเจ้าของบล็อคก็คิดเพื่อเอาเหตุผลมารองรับว่าทำไมต้องไปศึกษาด้วยฟ่ะเพราะ Java ก็โออยู่แล้วนะ เพราะอะไรล่ะ? ก็เขาว่าดีไง ก็เขาว่าคูลนะ ก็เขาว่า…

สิบปากว่าไม่เท่าตาเห็น สิบตาเห็นไม่เท่าลงมือทำ อย่างนั้นก็ลุยสิพ่อรออะไรเล่า 😎

วันเวลาผ่านไป… วันนี้เจ้าของบล็อคก็เลยขอมาสรุปสิ่งที่ได้จากการได้ลองลิ้มชิมรสภาษา Kotlin มาเป็นระยะเวลาประมาณหนึ่งเดือนกว่าๆ กันสักหน่อยว่ารสชาติที่เจ้า ของบล็อคได้ชิมนั้นเป็นยังไง แล้วทำไมเจ้าของบล็อคถึงได้หลงไหลไปกับรสชาตินั้น มาดูกันเลย ปู๊น ปู๊น

ปล.หากผิดพลาดประการใดต้องขออภัยไว้ ณ ที่นี้ด้วย

เริ่มจาก Kotlin คืออะไร?

Kotlin เป็นภาษาที่ใช้ในการเขียนโปรแกรมแบบ Statically-typed ที่ถูกรันบน Java Virtual Machine (JVM) ถูกพัฒนาขึ้นโดนทีม JetBrains โดยถูกออกแบบให้ทำงานร่วมกับโค้ด Java ได้อย่างสมบูรณ์ ซึ่งได้รับอิทธิพลมาจากภาษา Java, Scala, C#, Groovy, Gosu, JavaScript และ Swift

ซึ่งไฟล์ของ Kolin จะมีนามสกุลเท่ๆคือ .kt และมีตัว compiler ชื่อว่า kotlinc เช่นเดียวกับ Java ที่ชื่อ javac ซึ่งมีกระบวนการ compiler ดังภาพข้างล่างนี้

https://goo.gl/qFd8na

จากภาพจะเห็นได้ว่าจาก ไฟล์ .kt นั้นถูกแปลงให้เป็น .class และ .jar ตามลำดับแล้ว ไปรันบน JVM และเมื่อเปรียบเทียบกับ Java แล้วก็ไม่มีอะไรที่แตกต่างกัน เพราะ Kotlin นั้นถูกออกแบบมาเพื่อให้ใช้งานร่วมกับภาษา Java นั่นเอง

Kotlin พัฒนาแอพพลิเคชันอะไรได้บ้าง

ก็พอจะเข้าใจว่าเจ้า Kotlin ก็คือภาษาในการเขียนโปรแกรมภาษาหนึ่ง ซึ่งสามารถนำเอามาสร้างแอพฯ ดังนี้

  • พัฒนาแอพฯบนระบบ Android
  • ฝั่ง Server-side (JVM)
  • จาก JavaScript กลายมาเป็น Kotlin JavaScript
  • แม้กระทั่งแบบ Native เช่น iOS ก็มานะ

ทำไมต้อง Kotlin

  • Null Safety : เข้ามาช่วยลดความเจ็บปวดจากภาษา Java นั่นก็คือ Exceptions ที่ติดอันดับเป็นที่หนึ่งตลอดกาลอย่าง NullPointerException นั่นเอง
  • Concise : ทำให้โค้ดที่ยืดยาวเหมือนขอบชีสของพิซซ่า ให้เหลือเพียงไม่กี่บรรทัดตอนท้ายจะมีตัวอย่างโค้ดให้ดูอีกที
  • Functional Programming : ทำให้โค้ดดูแพงขึ้นมาทันที เช่น การเขียนโดยใช้ Lambdas และ Higher-Order Functions เป็นต้น
  • 100% interoperable with Java : ทำงานร่วมกับภาษา Java ได้อย่างสมบูรณ์ ไฟล์ .java สามารถเรียกใช้ไฟล์ .kt ได้ และ .kt ก็เรียกใช้งาน .java ได้เช่นกัน
  • Tool-friendly : เรื่อง Tool ในการใช้พัฒนาก็แสนจะสบาย เพราะเป็นภาษาของทีม JetBrains มันก็ต้อง IntelliJ IDEA อยู่แล้ว แต่ก็มี Editor อื่นๆ ที่ support อยู่เช่น Visual Studio Code
  • Google support : ในงาน Google I/O 2017 ที่พึ่งพามาก็ได้ประกาศให้โลกรู้ว่าตอนนี้ทาง Google เองนั้น support การพัฒนาแอพแอนดรอยด้วย Kotlin เรียบร้อยแล้ว ซึ่งประเด็นนี้มีนัยสำคัญบ่งบอกว่านักพัฒนาแอพแอนดรอยด์ว่าไม่ศึกษา Kotlin ไว้ไม่ได้แล้ว

พล่ามมาซะยาวไปดูรูปร่างหน้าตาของภาษา Kotlin กันเลย

อุ่นเครื่องด้วย Hello World

https://kotlinlang.org

ข้อสังเกต สิ่งที่หายไปอย่างเห็นได้ชัดจาก Java คือ ตัว ; และด้วยตัว Kotlin นั้นมีความเป็น Functional จึงสามารถสร้าง main function เพื่อรันได้ทันทีโดยไม่ไปแอบซ่อนอยู่ในคลาสเหมือนใน Java

การประกาศตัวแปร (Variable)

syntax : val หรือ var ชื่อตัวแปร : ชนิดของตัวแปร (optional)

val firstName : String = "20Scoops"
val lastName = "CNX"
var address : String = "Chiang mai"
var age = 23

ข้อสังเกต ถ้าหากไม่ได้กำหนด type ก็จะทำการกำหนดให้จากค่าของตัว แปร เช่น ตัวแปร lastName มีค่าเป็น String ก็จะกำหนด type เป็น String เพราะว่า Kotlin เป็นการเขียนโปรแกรมแบบ Statically-typed ซึ่งจะซีเรียสเรื่องของ type

ความแตกต่างระหว่าง val กับ var

  • val คือ ตัวแปรที่ไม่สามารถเปลี่ยนแปลงรูปได้ (immutable) เหมือนกับ final (ค่าคงที่) ของ Java เลยครับสามารถกำหนดค่าได้แค่ครั้งเดียว เช่น ถ้าเจ้าของบล็อคจะเปลี่ยนค่าตัวแปร firstName เป็นคำอื่นไม่ได้
  • var คือ ตัวแปรที่สามารถเปลี่ยนแปลงรูปได้ (mutable) ตัวแปรแบบปกติ

การประกาศฟังก์ชัน (Function)

syntax : fun ชื่อฟังก์ชัน (พารามิเตอร์…)

//return void 
fun speak(name: String, age: Int) {
println("My name is $name, I'm $age years old")
}
//return int
fun plus(x: Int, y: Int): Int {
return x + y
}

จะเห็นได้ว่า Kotlin เป็นภาษาที่เขียนสนุก เพราะ fun … (ทำไมคนอื่นเล่น แล้วฮาอะ) จากตัวอย่างด้านบนก็เป็นการสร้างฟังก์ชันธรรมดา แต่ Kotlin สามารถสร้างฟังก์ชันที่เป็นลักษณะอื่นๆได้ เช่น

ฟังก์ชันที่มี body เป็น expression

fun plus(x: Int, y: Int): Int  = x + y//ย่อได้อีก
fun plus(x: Int, y: Int) = x + y
//conditional expressions
fun maxOf(a: Int, b: Int) = if (a > b) a else b

ฟังก์ชันที่มี Arguments มีค่า default

fun speak(name: String = "20Scoops", age: Int = 23) {
println("My name is $name, I'm $age years old")
}
//เวลาเรียกใช้งาน
fun main(args: Array<String>) {
speak()
//output : My name is 20Scoops, I'm 23 years old
speak("Jedsada")
//output : My name is Jedsada, I'm 23 years old
speak(age = 25)
//output : My name is 20Scoops, I'm 25 years old
}

จากโค้ดตัวอย่างการกำหนด Aragument ให้มีค่า default นั้นมีนัยสำคัญคือทำให้เราลดการเขียน Overload Functions นั่นเอง

การสร้างคลาส (Classes)

syntax : class ชื่อคลาส {…}

class Student {
...
}
fun main(args: Array<String>) {
//ทำการสร้าง obj Student
val student = Student()
}

ข้อสังเกต การสร้าง Class ของ Kotlin นั้นไม่ต้องมีวงเล็บ และการสร้าง Object ก็มีความแตกต่างจาก Java โดยที่ไม่ต้องมี keyword new และในส่วนของการสร้าง constructor ก็จะมีความแตกต่าง ดังนี้

class Student(var name: String) {

init {
println("Student initialized")
}

fun speak() {
println("My name is $name")
}
}

fun main(args: Array<String>) {
//ทำการสร้าง obj Student
val student = Student("20Scoops CNX")
student.speak()
}

ซึ่งในส่วนของวงเล็บหลังชื่อคลาสจะถูกยกให้เป็น constructor และถ้าเราใส่ val หรือ var ที่ตัวแปรใน constructor ฟังก์ชันในคลาสนั้นก็จะสามารถเข้าถึงตัวแปรได้เลย และโดยปกติการกำหนดค่าเริ่มต้นใน Java จะต้องไปทำที่ constructor เพราะเป็น method แรกที่ถูกแรกเมื่อคลาสถูกสร้างขึ้น แต่ใน Kotlin จะให้ไปทำที่ blocks ที่ชื่อว่า init แทน เพราะ blocks init จะถูกเรียกครั้งแรกแทน constructor

การ Inheritance และ Implement

โดยปกติในภาษา Java นั้นการสืบทอดคลาส และการ Implement ของ Interface ก็จะถูกแยกด้วย keyword extedns กับ implement ซึ่งใน Kotlin keyword เหล่านี้จะถูกตัดออก ก็จะกลายร่างเป็นแบบนี้แทน

open class Human {
...
}

interface Humanable {
fun run()
}

class Student : Human(), Humanable {
override fun run() {
// TODO : somethings
}
}

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

Null Safety นี้แหละพระเอกของงาน

ปัญหาที่เกิดบ่อยขึ้นในภาษา Java ก็คงหนีไม่พ้นในเรื่องของ NullPointerException ซึ่งภาษา Kotlin ได้ถูกออกแบบเพื่อเข้ามาแก้ไข้ปัญหาเป็นเครื่องหมายการค้าของภาษานี้เลยก็ว่าได้ เอาละมาดูวิธีการทำกันสักหน่อย

ภาษา Java
String name = null;
System.out.println(name.length()); //เกิด NullPointerException
วิธีแก้ไข
String name = null;
if (name != null) {
System.out.println(name.length());
} else {
System.out.println("name is null");
}
ภาษา Kotlin
val name: String? = null
println(name?.length)

ข้อสังเกต ในภาษา Kotlin นั้นเครื่องหมาย ? ที่อยู่หลัง type ของตัวแปร name หมายถึงอนุญาตให้สามารถมีค่าเป็น null ได้ (Nullable) และถ้าหากจะเรียกใช้ property ของตัวแปรที่เป็น Nullable ก็มีวิธีเรียกใช้ด้วยกันสองแบบคือ

  • Safe Calls : เป็นการเรียกใช้งานแบบปลอดภัยโดยให้ใส่เครื่องหมาย ?.ตามด้วย property เช่น name?.length เพียงเท่านี้ก็สามารถลดความเจ็บปวดจากการเกิด NullPointerException ได้แล้ว
  • !! Operator : เป็นการเรียกใช้งานแบบว่าเรามั่นใจเลยว่าตัวแปรนั้นมีค่าโดยให้ใส่เครื่องหมาย !!.ตามด้วย property เช่น name!!.length แต่ถ้าหาก name มีค่าเป็น null เมื่อไหร่ละก็ NullPointerException อยู่ดีนะจ้าแต่จะเป็น Exception จาก Kotlin นะ

แต่ถ้าหากต้องการกำหนดค่าให้เก็บตัวแปรเมื่อมีค่าเป็น null ก็สามารถ if-else เช็ค null ไป ซึ่งดูไม่ค่อยแตกต่างจาก Java เท่าไร แต่สิ่งที่ Kotlin ดูแพงกว่า Java คือ

Elvis Operator คือ เครื่องหมาย ?: ซึ่งหลักการก็เหมือน if-else แต่วิธีการเขียนดู แพงกว่าเยอะ แพงกว่ายังไงไปดูกัน…

ปกติใน Java
String name = null;
if (name == null) {
name = "20Scoops CNX";
}
System.out.println(name);
Elvis Operator ใน Kotlin
val name: String? = null
println(name ?: "20Scoops CNX")

Control Flow ในแบบของ Kotlin

ในการเขียนโปรแกรมนักพัฒนาทุกคนคุ้นชินกับการเขียน condition ด้วย if-else หรือ switch case แต่ Kotlin นั้นมีความเป็น Functional Programming อยู่จึงทำให้เกิดการสร้างเงื่อนไขด้วย keyword ใหม่ที่ชื่อว่า when ตัวอย่าง

var number: Int = 5แบบธรรมดาไม่ใส่ใข่
if ((number % 2) == 0) {
number += 2
} else {
number += 1
}
แบบ when ใส่ไข่เพิ่มกล้วย
when (number % 2) {
0 -> number += 2
else -> number += 1
}

ข้อสังเกต จะเห็นว่ามีลูกศรใน block ของ when ซึ่งมันก็คือ Lambdas นั่นเอง

Data Classes ทำให้เหลือบรรทัดเดียว

ใครที่เขียน Java มาก่อนก็คงจะรู้สึกเจ็บปวดกับการเขียน POJO มากพอสมควรเพราะส่วนตัวเจ้าของบล็อคก็รู้สึกเหนื่อย ถึงแม้ว่า IDE จะช่วยเราในระดับที่สามารถ Generate ให้ก็ตามซึ่งใน Kottlin การทำ POJO จะมีหน้าตาแบบนี้

ข้อสังเกต การทำ POJO ใน Kotlin จะไม่ใช่ class ธรรมดาแต่จะเป็น data class แทนซึ่งจะจัดการกับพวก equals(), hashCode() และ toString() และตัวแปรใน Kotlin ก็มี getter และ setter ให้อยู่แล้วเลยไม่จำเป็นต้อง implement ออกมา

Extension function

เป็นขยายการเพิ่มฟังก์ชันเข้าไปใหม่ให้กับคลาส เช่น ถ้าต้องการทำ format ให้กับ String ใน Java ก็คงหนีไม่พ้นสร้างคลาส Util ขึ้นมาแต่ใน Kotlin นั้นสามาถเพิ่มฟังก์ชันใหม่ให้กับ String ได้ ตัวอย่าง

fun String.toBaht() = this.plus(" bath")

fun main(args: Array<String>) {
val price = "44"
println(price.toBaht())
}

ซึ่งทางที่ดีควรจะแยกไฟล์ เช่น Extensions.kt แล้วจะทำให้ String ทุกตัวที่อยู่ภายใน package เดียวกันจะมีคุณสมบัติ toBath() ทำให้ลดการเขียนพวก Utility ไปเยอะ

FindViewbyId หายไปใน Kotlin

สำหรับนักพัฒนาแอพแอนดรอย์ อย่างเช่นเจ้าของบล็อคก็คงรู้สึกว่าการที่เราต้อง findViewbyId เพื่อทำการผูก UI เข้ากับตัวแปรในการเข้าถึง view นั้นๆ เป็นเรื่องที่ขี้เกียจเอามากๆ จึงหา Library เพื่อเข้ามาช่วยจัดการอย่างเช่น Butter Knife หรือ Data Binding แต่ในภาษา Kotlin นั้นมี Extensions หนึ่งที่ช่วยปัญหานี้ ไปดูวิธีการเพิ่ม Extensions และการใช้งานกัน

ขั้นตอนแรกให้เพิ่ม Extension ในไฟล์ build.gradle (app) ดังนี้

apply plugin: 'kotlin-android-extensions'

android {
...
}

ขั้นตอนต่อไปก็มาทำหน้าตา UI โดยที่เจ้าของบล็อคออกแบบง่ายๆ ดังนี้

สุดท้ายก็มาลองเรียกใช้งาน textView ที่ชื่อว่า tv_test โดย Extensions ของ Kotlin ที่ไฟล์ MainActivity.kt ดังนี้

เห็นม่ะไม่ต้องประกาศตัวแปร และไม่ต้อง findViewById กันอีกแล้วสามารถเข้าถึง UI ได้เลยแต่ก็ต้องจำชื่อ id ของ View ที่จะใช้งานให้ได้ด้วยนะ (ถ้าเปลี่ยนจากชื่อ id ที่เป็น snake case มาเป็น camelcase เหมือนกับ Data Binding ให้จะดูคูลมากเลย)

นี้ก็เป็นเพียงเรื่องราวส่วนหนึ่งจากการเดินทางกับ Kotlin ของเจ้าของบล็อคเดี๋ยวจะยาวไปกว่านี้ก็ถือว่าเป็นเพียงน้ำจิ้มให้กับคนที่สนใจล่ะกันนะครับ และในส่วนของความสามารถของเจ้า Kotlin นั้นมีอีกเยอะแยะมากมาย ซึ่งสามารถเข้าไปศึกษาเพิ่มเติมไปพร้อมๆ กับเจ้าของบล็อคได้ที่

กลั่นกรองมาเป็นภาษาไทยก็มีเช่นกัน

สรุป

สำหรับการเดินทางไปกับเพื่อนใหม่ที่ชื่อว่า Kotlin ในระยะเวลาประมาณหนึ่งเดือนทำให้เจ้าของบล็อครู้สึกว่าการมาของภาษานี้ลดความเจ็บปวดจาก Java ลงไปได้เยอะ และยังมีความสามารถที่โคตรเจ๋งทำให้โค้ดดูแพงขึ้นมาแถมทาง Google ก็ยังสนับสนุนการเขียนแอพแอนดรอย์ด้วย Kotlin ทำให้ดูมีภาษีขึ้นมาและดูน่าจับสนใจเป็นอย่างมากซึ่งถ้าใครอยากเปลี่ยนจาก Java มาเป็น Kotlin นั้นไม่ต้องกังวลเพราะเจ้าบล็อครู้สึกว่าใครที่ได้ Java อยู่แล้วจะใช้ Learning curve ไม่ค่อยสูงมากส่งผลให้ตอนนี้เจ้าของบล็อคต้องขอฝากเนื้อฝากตัวกับมันไปซะล่ะ #TeamKotlin

--

--