Part 2: Kotlin Syntax, Null Safety and more in Android

Ở bài viết trước mình đã hướng dẫn các bạn bắt đầu kotlin trên android studio. Trong bài viết này chúng ta sẽ bắt đầu đi vào tìm hiểu các một số cú pháp cơ bản của kotlin và áp dụng ngay trên MainActivity.kt.

Kotlin Syntax

Bây giờ MainActivity của chúng ta là một tập tin Kotlin và chúng ta đã sẵn sàng để bắt đầu học cú pháp. Lần đầu tiên bạn nhìn nó có thể gây cho bạn một chút sợ hãi nhưng hãy tin tôi rằng bạn sẽ cảm thấy yêu nó ngay ! 😉

Kotlin được định nghĩa theo nhiều cách tuy nhiên câu dưới đây sẽ định nghĩa cho bạn:

Kotlin is a Concise, Safe and Statically typed programming language focused on Interoperability with Java.

Đầu tiên bạn hãy xem tập tin MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

So với java thì kotlin sẽ mất ít thời gian hơn để viết và đọc code vì vậy điều này sẽ cải thiện năng suất làm việc của bạn.

1.Extend and Implement

Hai từ khóa Extend Implement được thay thế bằng ký tự “:”.
Vậy nếu như java tôi sẽ phải dùng extend AppCompatActivity thì trong kotlin sẽ đơn giản như sau:

class MainActivity : AppCompatActivity()

2. Fun — ctions

Với Kotlin chúng ta không cần cấu trúc function “public void methodName()” như trong java nữa thay vào đó sẽ là từ khóa “fun” và kiểu trả về sẽ được thêm ở cuối hàm.
Vậy đâu là loại được trả về từ hàm “onCreate”?

override fun onCreate(savedInstanceState: Bundle?) {

Trong java khi không muốn trả về giá trị chúng ta sử dụng từ khóa “void” tuy nhiên trong kotlin nó sẽ được thay bằng “Unit” trình biên dịch sẽ biết rằng chúng ta không trả lại bất cứ giá trị nào và sẽ bỏ qua nó. Trong câu hỏi trên chúng ta sẽ thực hiện như sau:

override fun onCreate(savedInstanceState: Bundle?) : Unit {

3. Tạm biệt dấu “;” thần thánh

Trong Kotlin bạn không cần phải đặt dấu chấm phẩy vào cuối câu tuy nhiên kotlin vẫn cho phép và bạn vẫn có thể làm điều đó nếu bạn muốn ^^.

4. Values and Variable

Để định nghĩa một biến chúng ta sẽ dùng từ khóa “var” kiểu dữ liệu sẽ được tự động định nghĩa. Ngoài ra để tạo một biến constants chúng ta sẽ sử dụng từ khóa “val“.

val price = 100        // Int
price = 30             // don't compile! it's a constant
var total = price * 3  // Int
val name = "Juancho"   // String

Ngoài ra chúng ta cũng có thể định nghĩa rõ ràng như sau:

val lastname : String = "Keddit" // explicit type definition
var size : Double = 30.0
var time : Float = 15f

Có thể bạn thấy rằng chúng ta không có các kiểu dữ liệu nguyên thủy như : int, double,float… bởi vì “everything in Kotlin is an object”.

5. Properties and Fields

Trong Kotlin việc truy cập nào một thuộc tính tương tự như trong java. Thay vì gọi phương thức getResources ()  bạn cũng có thể gọi trực tiếp như sau:

resources.getString(R.string.id)
// vs
getResources().getString(R.string.id) // still allowed

Bạn vẫn có thể gọi phương thức getResource () nhưng Android Studio sẽ đề xuất bạn thay đổi nó:

6. Safe ?: Safe!

Đây là một trong những điều tuyệt vời về Kotlin so với java. Tất cả mọi thứ trong kotlin đều không null trừ khi bạn định nghĩa nó null. Để làm điều đó chúng ta sẽ sử dụng “?” dấu hỏi này cũng gợi ý cho bạn rằng giá trị có thể có hoặc không.

Dưới đây là một số ví dụ:

val a : String = null  // don't compile!
var b : Int          // neither as must be initialized or abstract.
val ok : String? = null // OK :)

Trình biên dịch sẽ kiểm tra một đối tượng không null, điều này sẽ ngăn cản việc gây ra lỗi “NullPointerException”.

7.Safe call

Để tương tác với một đối tượng nullable rất dễ, dấu “?” sẽ cho phép bạn nhận được giá trị trong trường hợp nó tồn tại, nếu không nó sẽ bỏ qua nó và bạn có thể tiếp tục chạy chương trình, còn với java sẽ gây crash :)))

val context : Context? = null
val res = context?.getResources() // not crash, res will be null

8. Smart cast

Nếu bạn vẫn làm việc với các đối tượng nullable bạn sẽ cần làm các việc như sau:

val context : Context? = null
val res = context?.getResources()
val appName = res?.getString(R.string.app_name)
val shortName = appName?.substring(0, 2)

Điều này thật khủng khiếp, nhưng bạn có thể làm điều này một cách tốt hơn với Smart case. Chỉ cần kiểm tra xem bối cảnh là null và bên trong block sẽ được coi như là một đối tượng không nullable:

val context : Context? = null
if (context != null) {
    val res = context.getResources()    // Don't need '?' anymore
    val appName = res.getString(R.string.app_name)
    val shortName = appName.substring(0, 2)
}
val context : Context? = null
context?.let {
    val res = context.getResources()    // Don't need '?' anymore
    val appName = res.getString(R.string.app_name)
    val shortName = appName.substring(0, 2)
}

9.Elvis Operator ?

Đây là tên gọi được sử dụng cho operator “?:” bạn có thể sử dụng nó để đưa ra một giá trị thay thế trong trường hợp đối tượng là null. Nó giống như một cách ngắn để thực hiện một kiểm tra null.
Trong ví dụ này “e.message” có thể là null, kiểu là “String?”. Trong trường hợp đối tượng không phải là null chúng ta sẽ gửi giá trị của thông báo, nếu không, giá trị mà chúng ta cung cấp sau toán tử Elvis: là “Error message”.

try {
    // code...
} catch (e: Throwable) {
    Log.e("TAG", e.message ?: "Error message")
}

Note: bạn có thể xem thêm nhiều hơn ở đây:
https://kotlinlang.org/docs/reference/null-safety.html

10. Statically Typed

Nó có nghĩa là Kotlin cần phải biết loại của tất cả mọi thứ mà bạn định nghĩa trong đonạ code của mình bởi vì trình biên dịch sẽ làm một kiểm tra trong quá trình biên dịch nó. Tuy nhiên trong IDE android studio nó cũng sẽ hỗ trợ bạn kiểm tra việc đã gán đúng hay chưa.

Hơn nữa, chúng ta không phải định nghĩa loại khi chúng ta tạo ra một biến, và nó sẽ được suy ra từ ngữ cảnh(context), một tính năng vô cùng tuyệt vời.

val toolbar = findViewById(R.id.toolbar) as Toolbar

Những lợi thế mang lại:

  • Độ tin cậy (Reliability): Trình biên dịch xác nhận tính đúng đắn của chương trình
  • Khả năng bảo trì (Maintainability) : code được giải thích bởi chính nó.
  • Công cụ hỗ trợ (Tool support): là những gì đã được đề cập ở phía trên (tatic typing enables reliable refactoring, code completion and more)
  • Hiệu suất (Performance): Trong hầu hết các trường hợp không cần phải tìm ra lúc chạy(runtime) mà là các method cần phải được gọi.

11. Tương tác với java 100%

Đây là một tính năng tuyệt vời khác về Kotlin, bạn có thể sử dụng mã Java từ file Kotlin và ngược lại. Trong ứng dụng Keddit, chúng tôi mở rộng từ AppCompatActivity, sử dụng đối tượng Bundle trong phương pháp onCreate và tất nhiên sử dụng tất cả các Android SDK để tạo App :). Ngoài ra, chúng tôi đang sử dụng thư viện Java khác như Retrofit, Picasso, v.v.

Một điều thực sự quan trọng là Kotlin không có thư viện sưu tập của riêng mình, nó dựa vào các lớp thư viện chuẩn của Java, mở rộng các lớp này với các chức năng mới. Điều này có nghĩa là bạn không bao giờ cần phải chuyển đổi các đối tượng giữa Java và Kotlin.

Updating MainActivity

Dưới dây là cách để mở một fragment và loại bỏ các đoạn code không cần thiết trong trường hợp này. Kiểm tra code bên dưới để hiểu rõ hơn

https://github.com/juanchosaravia/KedditBySteps/blob/master/app/src/main/java/com/droidcba/kedditbysteps/MainActivity.kt

Chú ý cách chúng tôi sử dụng Fragment Manager:

val ft = supportFragmentManager.beginTransaction();
// and not getSupportFragmentManager()

Phương pháp mới “changeFragment ()” sẽ cho phép chúng ta mở một fragment trong activity này với một fade animation.

KẾT LUẬN

Đây chỉ là một phần nhỏ của một số khái niệm của Kotlin, chúng ta sẽ tiếp tục học thêm trong các bài viết tiếp theo.

Nếu bạn muốn tìm hiểu thêm về những khái niệm này truy cập link sau: http://try.kotlinlang.org/

Twitter: https://twitter.com/juanchosaravia

Dịch tại : Medium

Nguyễn Linh

Chia sẻ để cùng tiến bộ...