Kotlin và những cái mới mẻ – Phần 1

Ở phần trước, chúng ta đã giới thiệu về Kotlin, những tồn tại của Java và những cái hay, cái mới mẻ mà Kotlin mang lại. Bạn nào chưa đọc có thể đọc tại đây:

Kotlin và Java: kế thừa và phát triển

Ở phần 2 này, chúng ta sẽ khám phá sâu hơn về Kotlin: những cái hay, cái mới mà nó mang lại.

Bài viết nằm trong Series Kotlin vi diệu, các bạn có thể xem tại:

Series Kotlin vi diệu: https://codecungtrung.com/kotlin/series-kotlin-vi-dieu/

Có những điều các bạn có thể không thấy như mình. Vậy nên hãy đọc rồi để lại comment nhé !!! Rất chờ đợi ý kiến từ các bạn.


Now Let’s go !!!

Cảm ơn bạn đã đọc các bài viết của Code cùng Trung. Bạn hãy ủng hộ blog bằng cách:

  • Comment bên dưới mỗi bài nếu có thắc mắc
  • Để lại địa chỉ email của bạn để nhận được thông báo sớm nhất khi có bài viết mới
  • Chia sẻ các bài viết của Code cùng Trung đến nhiều người khác

I. Smart cast 

a. Vấn đề

Trong Java, ta viết như sau

public void doSomething(Object anything) {
if (anything instanceof String) {
// Phải tự cast sang kiểu (String)
Log.d("Do st", ((String) anything).toUpperCase());
}
if (anything instanceof Integer) {
// Phải tự cast sang kiểu (Integer)
Log.d("Do st", String.valueOf(((Integer) anything) * 3));
}
}

Ta phải tự cast sang kiểu dữ liệu tương ứng. Và dùng mấy cái ngoặc ngoặc ())(()() thực sự nhiều lúc mình thấy khá khó chịu, nhìn loạn cả mắt :((

Và Kotlin solution

fun doSomething(anything: Any) {
if (anything is String) {
Log.d("Do st", anything.toUpperCase())
}
if (anything is Int) {
Log.d("Do st", (anything * 3).toString())
}
}

Ơ, không cần ()(()) nhể, trông gọn hơn hẳn nữa !!!

2. Chi tiết

Đây chính là smart cast trong Kotlin. Giúp bỏ đi ())()()() khó chịu, cũng khỏi phải viết tự cast luôn. Ta sử dụng is, !is cho việc này

Code sẽ hiện ra như hình, hay chưa !!!

Tự cast sang nếu biết check ngược trả về null

Lỗi trong Java

Để fix thì đương nhiên viết ((String) anything).toUpperCase() là ok

Nhưng sang Kotlin thì

Kotlin cũng tương tự nhưng không lỗi nè (Wow)

Chi tiết hơn thì mình sẽ để ở phần tham khảo nhé !!! Tiếp tục nào 😀

II. Data classes

1. Vấn đề

Code Java, hẳn nhiều lúc bạn cần những chức năng sau

  • get/set
  • Hàm khởi tạo constructor
  • Hàm equals() để so sánh
  • Hàm hashCode() để lấy hash code, cũng có thể dùng để so sánh
  • Hàm toString()

Và code trong Java để làm những điều trên, ta thường phải tự code. Hoặc có hỗ trợ nhưng ta vẫn phải chọn hàm để gen ra như sau

Chọn nào, chọn nào

Kết quả sau khi chọn, cả một tràng code luôn

76 dòng lận – nhưng chắc là cũng quen r :))

Dài, tốn thời gian – đó là cái ta có thể thấy ngay được.

Nhanh hơn được không ??? Được chứ, kotlin comes to rescue :)) Mấy dòng dưới là xong nè

What ?? Code trên là sao vậy ??

Trả lời: Tất cả đoạn code bằng Java ở trên, trong Kotlin chỉ có vậy thôi.

What ?? How ??

Wow ?? What ??

Tranh thủ sắm thôi

2. Chi tiết

Đó chính là data class trong Kotlin, mới phải không nào. Những gì nó làm được là những gì mình đã nói ở phần 1. Vài dòng đổi lấy … 76 dòng và thời gian, công sức chọn rồi phương thức để gen ra. Cool phải ko nào 😀

Ngoài ra còn bonus cho ta thêm hàm copy() để tạo copy ra, componentN() để lấy các thuộc tính, …

Và bạn có hỏi tại sao nó làm vậy được không, nhìn không thấy code … get/set, toString(), hashCode(), … đâu cả ?? Và đây là câu trả lời

Kotlin sẽ tự gen code ra cho chúng ta, done !!!

III. Scope function

1. Vấn đề

Code Java ta viết như sau

public void test() {
    Person alice = new Person("Alice", 20, "Amsterdam");
    println(alice);
    alice.moveTo("London");
    alice.incrementAge();
    println(alice);
    alice.moveTo("Ha Noi");
    alice.incrementAge();
    alice.moveTo("Dubai");
    alice.moveTo("Dubai");
    alice.moveTo("Dubai");
    println(alice);
}

Ta phải lặp lại việc viết “alice” mỗi lần cần gọi phương thức và quan trọng hơn ta phải tạo biến “alice” để có thể gọi phương thức :))

public ArrayList<Person> updateList() {
ArrayList<Person> listPerson = new ArrayList<>();
listPerson.add(new Person("A", 11, "Ha Noi"));
listPerson.add(new Person("B", 12, "Ha Noi"));
listPerson.add(new Person("C", 13, "Ha Noi"));
listPerson.add(new Person("D", 14, "Ha Noi"));
listPerson.add(new Person("E", 15, "Ha Noi"));
return listPerson;
}

Ta cũng phải lặp lại việc viết “listPerson” mỗi lần gọi “add” và cả phải tạo biến “listPerson” nữa :v

Một lô “alice” như hình

Tóm lại: việc lặp lại này sẽ khiến code dài hơn ==> Cũng mất thời gian đọc, code và khó đọc hơn :((

Nhưng có thể các bạn không thấy điều mình thấy, đúng chứ ??

Giờ thử cái dưới xem sao, ý nghĩa nó giống hệt đoạn code Java ở trên nhé

fun test() {
    Person("Alice", 20, "Amsterdam").let {
        println(it)
        it.moveTo("London")
        it.incrementAge()
        println(it)
        it.moveTo("Ha Noi")
        it.incrementAge()
        it.moveTo("Dubai")
        it.moveTo("Dubai")
        it.moveTo("Dubai")
        println(it)
    }
}
fun updateList() = ArrayList<Person>().apply {
add(Person("A", 11, "Ha Noi"))
add(Person("B", 12, "Ha Noi"))
add(Person("C", 13, "Ha Noi"))
add(Person("D", 14, "Ha Noi"))
add(Person("E", 15, "Ha Noi"))
}

Không thấy viết “alice” nữa rồi, mà “alice” đâu rồi ?? ( In wonder land chăng :)) )

Cũng không phải viết “listPerson” nữa, cũng chả thấy “listPerson” đâu luôn

Chỉ thấy các hàm tương tự bên Java

?????????????????????????????????????????

Trông nó cũng hay hay, ngắn hơn phần Java nào phải không.

Phần tiếp theo mình sẽ nói rõ hơn nhé. Let’s go 😀

2. Chi tiết

Đó chính là scope function, giúp code ngắn hơn, gọn hơn, tiết kiệm thời gian đọc

Kotlin cung cấp scope function: let, run, with, apply, also. Mỗi cái sẽ có một cách sử dụng khác nhau. Chi tiết mình sẽ để ở link phần tham khảo nhé.

==> Nhìn code ngắn hơn, đỡ lặp, rối mắt phải không nào

Và nếu bạn hỏi ma thuật đằng sau đó là gì ? Tại sao lại có thể làm được như vậy ?

Thì câu trả vẫn tương tự như ở mục II. Bộ complile của Kotlin sẽ làm cho ta phần còn lại, và nó sẽ compile ra Java đó. Viết ngắn hơn mà kết quả được tương tự, nên thử phải không nào !!!

Ma thuật thần bí !!!

Chi tiết cách code mình sẽ để ở phần Tham khảo nhé !!!

IV. Extenstion function

1. Vấn đề

Trong Java, muốn thêm code vào class thì phải … viết code trong class, extend lại class, sử dụng Decorator design pattern hoặc ko thể (như lib ngoài, class của hệ thống)

Ví dụ như sau

Hai điều ta thấy ở đây là:

  • Bị lỗi đỏ như trên là do đối tượng userDb, ko có phương thức checkValidateUser(). Và nếu muốn có ta phải viết cho nó ở … “trong class UserDb
  • Ta muốn check xem user name có hợp lệ không. Mà userName kiểu String ==> Class String cần có phương thức để check chẳng hạn, tương tự như các hàm indexOf(), concat(), … có sẵn. Nhưng … đương nhiên là không thể vì String là class của hệ thống ==> Phải tạo hàm checkValidUserName() riêng như trên ==> Nhìn khá loạn và không rõ ràng tẹo nào

Nhưng tiếp tục nào !!!

Giờ có thể viết lại mà ko cần như trên … Bùm

Nhiều cái lạ lạ :v

Chúng ta thấy gì nào

Trong hàm main()

  • Đã gọi được hàm checkValidateUser(), nhưng method này không viết trong class UserDb mà viết ở chỗ lạ lạ trong hình :))
  • Đối tượng userName – kiểu String đang gọi hàm checkValidUserName(). Code bên Java lỗi phải không nào ????

Đi tiếp đọc giải thích nào !!!

Hội sách tháng 3 này tại Tiki

2. Chi tiết

Đó là extension function trong kotlin. Ko cần viết code trong class, extend lại hay thậm chí thêm được method cho class của hệ thống, của lib ngoài.

Và bạn có phân vân … có gọi được những phương thức ở phần 1 ở những class khác trong Kotlin không, tạo sao lại làm được như vậy ??? Câu trả lời là … lần này … các bạn hãy thử tìm hiểu kiến thức mới này xem sao nhé :))

Tip – cho các bạn đã biết Kotlin

Bạn hay dùng Util Class không ?? Cho bạn chưa biết đó là tập hợp của những phương thức, công cụ hay dùng chuyên để làm gì đó như xử lý ảnh, load file, kết nối mạng, …

Trong Kotlin, ta có thể viết như hình là xong, nhanh gọn lẹ

Không có khai báo class à !!!!!!!!

Tóm lại

Ở phần 1 này chúng ta đã tìm hiểu về 4 khái niệm mới trong Kotlin là:

  • Smart cast
  • Data classes
  • Scope function
  • Extension function

Chúng ta cũng đã so sánh với code bên Java, phân tích, so sánh code giữa hai bên.

Ở phần sau chúng ta sẽ tiếp tục đi khám phá những điều mới mẻ của Kotlin nhé.

Bài viết nằm trong Series Kotlin vi diệu, hãy xem tại đây

Nhiều cty cũng bắt đầu code Kotlin rồi, nhiều người bắt đầu code bằng Kotlin, cộng đồng Kotlin đang phát triển mạnh.

Làn gió mới Kotlin – hãy thử ngay thôi nào 😀

Bạn nào có nhu cầu học Kotlin có thể tham khảo khóa học sau của Duy Thanh – một cái tên rất nổi tiếng nhé, rất chi tiết và bổ ích đó !

Tham khảo

Đọc chi tiết các phần hơn tại

  1. Smart cast: https://kotlinlang.org/docs/reference/typecasts.html
  2. Data classes: https://kotlinlang.org/docs/reference/data-classes.html
  3. Scope function: https://kotlinlang.org/docs/reference/scope-functions.html
  4. Extension function: https://kotlinlang.org/docs/reference/extensions.html

Tham khảo khác:

5. https://proandroiddev.com/kotlin-made-casting-so-much-neater-657c165c4858

6. https://medium.com/androiddevelopers/kotlin-demystified-scope-functions-57ca522895b1

Cảm ơn bạn đã đọc các bài viết của Code cùng Trung. Bạn hãy ủng hộ blog bằng cách:

  • Comment bên dưới mỗi bài nếu có thắc mắc
  • Để lại địa chỉ email của bạn để nhận được thông báo sớm nhất khi có bài viết mới
  • Chia sẻ các bài viết của Code cùng Trung đến nhiều người khác

5 thoughts on “Kotlin và những cái mới mẻ – Phần 1”

Leave a Reply