Tại sao chúng ta nên chuyển sang Kotlin
Bài đăng này đã không được cập nhật trong 7 năm
Đã đế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 Intellij và ReSharper.
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 val
và var
.
Đ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", "john@gmail.com", 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.
All rights reserved