Tại sao chúng ta nên chuyển sang Kotlin

Đã đến lúc bắt đầu sử dụng một ngôn ngữ lập trình hiện đại

Chúng ta sẽ cùng tìm hiểu về một ngôn ngữ lập trình mới gọi là Kotlin và tại sao nên xem xét dùng nó cho dự án tiếp theo. Chúng ta có thể đã quen thuộc và cảm thấy yêu thích Java, nhưng khi làm việc với kotlin nhiều sẽ nhận thấy code được với kotlin bất cứ khi nào có thể và nó sẽ là sự lựa chọn tốt hơn so với Java.

Kotlin được phát triển bởi JetBrains, chính là đội ngũ đứng đằng sau bộ IDE IntellijReSharper.

Mặc dù Kotlin được biên dịch cho cả JavaScript cũng như machine code, tuy nhiên chúng ta sẽ tập trung vào môi trường chính là JVM

Sau đây là những lý do chúng ta nên chuyển sang Kotlin:

#0 - Khả năng tương thích với Java

Kotlin tương thích 100% với Java. Chúng ta thực sự có thể tiếp tục làm việc trên các dự án cũ đã phát triển với Java bằng cách sử dụng Kotlin. Tất cả các Java framework sẽ vẫn available.

#1 - Cú pháp quen thuộc

Kotlin không phải là một ngôn ngữ kỳ lạ sinh ra trong học viện để nghiên cứu. Cú pháp của nó quen thuộc với bất cứ lập trình viên nào đã làm việc với OOP. Tất nhiên, có một số khác biệt so với Java như các contructor hay khai báo biến valvar. Đoạn dưới đây trình bày hầu hết những điều cơ bản:

class Foo {

    val b: String = "b"     // val means unmodifiable
    var i: Int = 0          // var means modifiable

    fun hello() {
        val str = "Hello"
        print("$str World")
    }

    fun sum(x: Int, y: Int): Int {
        return x + y
    }

    fun maxOf(a: Float, b: Float) = if (a > b) a else b

}

#2 - String Interpolation

Nó giống như một phiên bản thông minh và dễ đọc hơn của hàm Java String.format():

val x = 4
val y = 7
print("sum of $x and $y is ${x + y}")  // sum of 4 and 7 is 11

#3 - Type Inference

Kotlin sẽ tự suy ra được kiểu dữ liệu

val a = "abc"                         // type inferred to String
val b = 4                             // type inferred to Int

val c: Double = 0.7                   // type declared explicitly
val d: List<String> = ArrayList()     // type declared explicitly

#4 - Smart Casts

Trình biên dịch Kotlin theo dõi logic và tự động ép kiểu nếu có thể, có nghĩa là không cần kiểm tra instanceof:

if (obj is String) {
    print(obj.toUpperCase())     // obj is now known to be a String
}

#5 - Intuitive Equals

Bạn có thể không cần gọi equal() một cách rõ ràng bằng cách sử dụng ==

val john1 = Person("John")
val john2 = Person("John")
john1 == john2    // true  (structural equality)
john1 === john2   // false (referential equality)

#6 - Default Arguments

Chúng ta không cần định nghĩa các method tương tự nhau với các đối số khác nhau:

fun build(title: String, width: Int = 800, height: Int = 600) {
    Frame(title, width, height)
}

#7 - Named Arguments

Kết hợp với các argument mặc định, sử dụng named argument sẽ không cần Builder Pattern:

build("PacMan", 400, 300)                           // equivalent
build(title = "PacMan", width = 400, height = 300)  // equivalent
build(width = 400, height = 300, title = "PacMan")  // equivalent

#8 - Biểu thức When

Switch - case được thay thế bằng biểu thức when linh hoạt hơn:

when (x) {
    1 -> print("x is 1")
    2 -> print("x is 2")
    3, 4 -> print("x is 3 or 4")
    in 5..10 -> print("x is 5, 6, 7, 8, 9, or 10")
    else -> print("x is out of range")
}

Nó hoạt động như một biểu thức hoặc một câu lệnh, và có hoặc không có đối số:

val res: Boolean = when {
    obj == null -> false
    obj is String -> true
    else -> throw IllegalStateException()
}

#9 - Thuộc tính Properties

Tuỳ chỉnh được set và get cho các public field

class Frame {
    var width: Int = 800
    var height: Int = 600

    val pixels: Int
        get() = width * height
}

#10 - Data Class

Đó là một POJO hoàn chỉnh với toString(), equals(), hashCode(), và copy() với ít dòng code hơn so với Java:

data class Person(val name: String,
                  var email: String,
                  var age: Int)

val john = Person("John", "[email protected]", 112)

#11 - Operator Overloading

Một tập toán tử (operator) có thể được overload để cải thiện khả năng đọc:

data class Vec(val x: Float, val y: Float) {
    operator fun plus(v: Vec) = Vec(x + v.x, y + v.y)
}

val v = Vec(2f, 3f) + Vec(4f, 1f)

#12 - Destructuring Declarations

for ((key, value) in map) {
    print("Key: $key")
    print("Value: $value")
}

#13 - Ranges

for (i in 1..100) { ... } 
for (i in 0 until 100) { ... }
for (i in 2..10 step 2) { ... } 
for (i in 10 downTo 1) { ... } 
if (x in 1..10) { ... }

#14 - Extension Functions

Khi sắp xếp với List trong Java, bạn không thể tìm thấy một chức năng sort() mà phải tìm hiểu Collection.sort(). Tuy nhiên, với kotlin chúng ta có thể dễ dàng định nghĩa thêm các method mà không cần extend:

fun String.format(): String {
    return this.replace(' ', '_')
}

val formatted = str.format()

#15 - Null Safety

Java là một ngôn ngữ static. Một biến kiểu String có thể là một chuỗi hoặc null. Chúng ta phải quen với một Null Point Exception. Kotlin giải quyết vấn đề này bằng cách phân biệt kiểu non-null và nullable. Mặc định là non-null, và chúng ta có thể khai báo kiểu nullable bằng việc thêm ? như sau:

var a: String = "abc"
a = null                // compile error

var b: String? = "xyz"
b = null                // no problem

Kotlin sẽ cảnh báo một Null Point Exception bất cứ khi nào chúng ta truy cập kiểu nullable:

val x = b.length        // compile error: b might be null

Mặc dù có thể sẽ rườm rà, nhưng chúng ta chắc chắn sẽ tránh được NPE

if (b == null) return
val x = b.length        // no problem

Ngắn gọn hơn, chúng ta có thể sử dụng ?.

val x = b?.length       // type of x is nullable Int

Các lời gọi an toàn có thể nối tiếp nhau:

val name = ship?.captain?.name ?: "unknown"

#16 - Sử dụng Lamdas

Kotlin có hỗ trợ lamdas:

val sum = { x: Int, y: Int -> x + y }   // type: (Int, Int) -> Int
val res = sum(4,7)                      // res == 11
numbers.filter({ x -> x.isPrime() })
numbers.filter { x -> x.isPrime() }
numbers.filter { it.isPrime() }
persons
    .filter { it.age >= 18 }
    .sortedBy { it.name }
    .map { it.email }
    .forEach { print(it) }

Kết luận

Như vậy, cú pháp kotlin cực kỳ ngắn gọn và có những ưu điểm của một ngôn ngữ hiện đại so với Java. Với các developer phát triển Android, chúng ta lại đón nhận thêm tin vui rằng Google đã hỗ trợ Kotlin từ phiên bản Android Studio 3.0. Kotlin hứa hẹn sẽ ngày càng phổ biến rộng rãi trong cộng đồng Android.