Biến, giá trị, hằng, và kiểu dữ liệu trong Kotlin

    1

    Biến, hằng, và kiểu dữ liệu là những đơn vị cơ bản của chương trình trong Kotlin. Biến và hằng có nhiệm vụ lưu trữ dữ liệu. Kiểu quy định những giá trị cụ thể mà biến và hằng có thể lưu trữ.

    Kotlin là một ngôn ngữ định kiểu tĩnh (statically typed) và định kiểu mạnh (strongly typed), tương tự như Java và C#. Do vậy quá trình khai báo và sử dụng biến trong Kotlin có rất nhiều điểm tương đồng với các ngôn ngữ trên.

    Tuy nhiên, Kotlin có một số điểm khác biệt quan trọng.

    Khai báo biến trong Kotlin

    Chúng ta tiếp tục với project HelloKotlin đã tạo từ bài học “cài đặt IDE cho Kotlin“. Tạo mới file Variable.kt trong thư mục src và viết code như sau:

    fun main() {
        var name : String = "Donald Trump"
        var age : Int = 74
        var height : Double = 1.89
        var male : Boolean = true
        println(name)
        println(age)
        println(height)
        println(male)
    }
    

    Chạy thử Variable.kt (Ctrl + Shift + F10) sẽ thu được kết quả như sau:

    Chương trình ví dụ khai báo biến trong Kotlin

    Nhóm lệnh

    var name : String = "Donald Trump"
    var age : Int = 74
    var height : Double = 1.89
    var male : Boolean = true

    là các lệnh khai báo biến trong Kotlin.

    Cú pháp chung của lệnh khai báo biến trong Kotlin như sau:

    var tên_biến : kiểu = giá_trị

    Theo cú pháp trên:

    • Việc khai báo biến bắt đầu với từ khóa var, tiếp theo là tên biến.
    • Khi khai báo biến trong Kotlin cần chỉ định rõ kiểu dữ liệu mà biến đó sẽ chứa. Kiểu dữ liệu viết tách với tên biến qua dấu hai chấm.
    • Khi khai báo biến thường sẽ gán luôn giá trị. Để gán giá trị bạn dùng phép gán = và giá trị phù hợp sau đó.

    Kiểu dữ liệu trong Kotlin

    Việc khai báo biến trong Kotlin luôn phải đi kem với xác định kiểu dữ liệu. Trong ví dụ trên bạn đã gặp các kiểu dữ liệu Int, Double, Boolean, và String.

    Kho kiểu dữ liệu trong Kotlin rất phong phú, bao gồm những kiểu tích hợp sẵn cũng như các kiểu từ thư viện (riêng của Kotlin hoặc thư viện Java).

    Trong bảng dưới đây chúng ta liệt kê một số kiểu dữ liệu thông dụng và sẽ học chi tiết trong các bài học tương ứng.

    Tên kiểuÝ nghĩaVí dụ
    StringKiểu chuỗi ký tự
    CharKiểu ký tự
    BooleanKiểu logic
    IntKiểu số nguyên
    DoubleKiểu số thực
    ListKiểu danh sách
    SetKiểu tập hợp
    MapKiểu mảng kết hợp

    Trong các kiểu dữ liệu trên, String, Char, Boolean, Int hay Double là những kiểu dữ liệu cơ bản, trong khi List, Set hay Map là những kiểu dữ liệu phức tạp.

    Tên gọi các kiểu dữ liệu cơ bản của Kotlin khá tương đồng với các ngôn ngữ khác.

    Trong các bài học tiếp theo chúng ta sẽ lần lượt học chi tiết về các kiểu dữ liệu này.

    Các vấn đề khi sử dụng biến trong Kotlin

    Khi sử dụng biến trong Kotlin cần lưu ý các vấn đề sau.

    (1) Tên biến cần tuân thủ quy tắc đặt định danh chung của Kotlin:

    • Tên biến chỉ chứa chữ cái (a-z, A-Z), chữ số (0-9), và dấu gạch chân _;
    • Tên biến chỉ được bắt đầu bằng chữ cái hoặc dấu gạch chân;
    • Tên biến phân biệt hoa / thường.

    Kotlin cho phép (nhưng không khuyến khích) sử dụng các chữ cái Unicode trong định danh, nghĩa là bạn có thể đặt tên biến bằng tiếng Việt có dấu nếu muốn. Nhìn chung bạn chỉ nên sử dụng các chữ cái ASCII khi đặt tên trong Kotlin.

    (2) Kotlin quy ước đặt tên biến theo kiểu camelCase:

    • Tất cả các ký tự viết thường;
    • Nếu tên bao gồm nhiều từ thì viết hoa chữ cái đầu mỗi từ, ngoại trừ từ đầu tiên.

    Bạn không nên sử dụng dấu gạch chân giữa các từ trong tên gọi.

    (3) Kotlin yêu cầu phải chỉ định kiểu khi khai báo biến. Đặc điểm này khiến Kotlin thuộc vào nhóm ngôn ngữ định kiểu tĩnh (statically typed).

    Nhờ việc chỉ định kiểu, IDE và Kotlin compiler có thể xác định những lệnh sử dụng kiểu không phù hợp ngay từ giai đoạn viết code và biên dịch. Nó giúp code Kotlin an toàn hơn.

    (4) Kotlin yêu cầu giá trị gán cho biến phải phù hợp với kiểu đã chỉ định. Nói cách khác, một biến không được phép nhận giá trị thuộc kiểu khác với kiểu trong khai báo. Đặc điểm này làm Kotlin là ngôn ngữ định kiểu mạnh (strongly typed).

    Ví dụ, một biến được khai báo với kiểu Int sẽ không thể nhận giá trị kiểu String.

    Báo lỗi khi giá trị không phù hợp với kiểu của biến trong IntelliJ IDEA

    Thậm chí, một biến được khai báo với kiểu Int sẽ không thể nhận giá trị kiểu Double, mặc dù chúng cùng là số.

    Trong một số trường hợp, Kotlin có thể hỗ trợ chuyển đổi kiểu. Bạn cũng có thể tự mình gọi các hàm chuyển đổi kiểu dữ liệu khi cần thiết. Chúng ta sẽ nói về chuyển đổi kiểu khi học về dữ liệu kiểu số và chuỗi trong các bài học sau.

    (5) Việc gán giá trị là không bắt buộc khi khai báo biến. Tuy nhiên, Kotlin yêu cầu biến phải được gán giá trị trước khi sử dụng.

    Nếu bạn sử dụng một biến mà chưa gán giá trị cho nó, IntelliJ IDEA sẽ giúp báo lỗi như sau:

    Thông báo lỗi khi sử dụng biến mà không gán giá trị trong IntelliJ IDEA

    Suy đoán kiểu

    Hãy điều chỉnh code ví dụ trên như sau:

    fun main() {
        var name = "Donald Trump"
        var age = 74
        var height = 1.89
        var male = true
        println(name)
        println(age)
        println(height)
        println(male)
    }

    Nếu chạy file bạn thu được cùng kết quả. Sự khác biệt của đoạn code trên ở chỗ: trong lệnh khai báo biến không có chỉ định kiểu.

    Đây là một tính năng của Kotlin: suy đoán kiểu.

    Khi bạn khai báo đồng thời gán giá trị cho biến, Kotlin có khả năng tự suy đoán ra kiểu từ giá trị. Do vậy Kotlin cho phép (và khuyến khích) bỏ chỉ định kiểu ra khỏi lệnh khai báo biến giúp làm code ngắn gọn hơn.

    Suy đoán kiểu không làm thay đổi bản chất định kiểu tĩnh của Kotlin. Ở đây do Kotlin có thể tự suy đoán ra kiểu qua giá trị nên nó sẽ tự động sử dụng kiểu đó khi dịch code.

    Nếu muốn sử dụng tính năng suy đoán kiểu của Kotlin, khi khai báo biến bạn bắt buộc phải kết hợp cùng gán giá trị. Nếu thiếu phần gán giá trị, Kotlin không thể suy đoán được kiểu và sẽ báo lỗi:

    Tính năng này giống hệt như suy đoán kiểu của biến trong C# với từ khóa var.

    IntelliJ IDEA có khả năng phân tích code ngay khi bạn viết để đưa ra lời nhắc. Đối với trường hợp có thể bỏ chỉ định kiểu, tên kiểu trong khai báo biến sẽ hiển thị mờ hơn bình thường.

    Đặt con trỏ văn bản vào tên kiểu và ấn Alt + Enter để mở menu Context Action:

    Context Action (Alt + Enter) trong trường hợp có thể bỏ chỉ định kiểu

    Lựa chọn “Remove explicit type specification” sẽ tự động bỏ đi chỉ định kiểu trong khai báo biến.

    Nếu có nhiều vị trí khác trong file cần xử lý tương tự, bạn có thể mở tiếp menu con và chọn Fix all 'Explicit given type is redundant here' problems in file.

    Giá trị / biến chỉ đọc val trong Kotlin

    Trong Kotlin, ngoài loại biến khai báo với từ khóa var như đã xem xét ở trên còn một loại biến nữa, gọi là giá trị (value) hoặc biến chỉ đọc (readonly variable).

    Giá trị / biến chỉ đọc là những biến mà giá trị của nó không đổi sau khi được định nghĩa. Loại biến này cũng thường được gọi là giá trị bất biến (immutable variable / value).

    Biến val là loại giá trị được tạo ra nhằm phục vụ cho xu hướng lập trình hàm (functional programming).

    Kotlin khuyến khích sử dụng loại giá trị này so với biến var.

    Biến chỉ đọc trong Kotlin được định nghĩa giống hệt như đối với biến. Khác biệt ở chỗ, để khai báo loại biến này chúng ta sử dụng từ khóa val. Bản thân từ khóa val là viết gọn của value.

    Để tiện lợi, chúng ta sẽ gọi loại biến thông thường (khai báo với từ khóa var) là biến var, còn biến chỉ đọc (khai báo với từ khóa val) là biến val.

    fun main() {
        val name : String = "Donald Trump"
        val age : Int = 74
        val height : Double = 1.89
        val male : Boolean = true
        println(name)
        println(age)
        println(height)
        println(male)
    }

    Đối với biến val bạn cũng có thể sử dụng cơ chế suy đoán kiểu giống như biến var:

    Lưu ý, mặc dù có giá trị không đổi, biến khai báo bằng từ khóa val không thực sự là hằng như cách hiểu thông thường. Chúng ta sẽ nói về hằng và so sánh với biến val ở phần sau của bài học này.

    Khi sử dụng IntelliJ IDEA, biến var được gạch chân, còn hằng val được thể hiện bình thường:

    Nếu trong code của bạn có quá nhiều chỗ gạch chân (var), hãy xem xét lại một lượt.

    Như vậy, trong Kotlin có hai loại biến: biến var (có thể thay đổi) và biến val (biến / giá trị chỉ đọc). Biến var dùng cho lập trình hướng đối tượng (và xu hướng lập trình imperative nói chung). Biến val dùng cho xu hướng lập trình hàm.

    Hằng trong Kotlin, val và const val

    Bạn cũng có thể khai báo hằng với từ khóa const val:

    Đây mới là loại “hằng” thực sự mà bạn đã quen thuộc ở các ngôn ngữ lập trình khác.

    Lưu ý, val có thể khai báo trong thân hàm giống như var, const val phải khai báo ngoài hàm. Chúng ta sẽ nói về sự khác biệt này khi học về lập trình hướng đối tượng trong Kotlin.

    Bạn liệu có thắc mắc tại sao cùng khai báo “hằng” mà có hai cách khác nhau, sử dụng từ khóa valconst val.

    Để phân biệt hai anh này chúng ta cần hiểu hai khái niệm: runtime constantcompile time constant. Hai khái niệm niệm này không phải là đặc trưng riêng của Kotlin.

    Runtime constant là những giá trị được tạo ra khi chương trình chạy và giữ nguyên giá trị sau đó. Nó chỉ được coi là hằng khi chương trình đang hoạt động. Mỗi lần chương trình chạy nó có thể nhận giá trị khác nhau (nhưng sẽ không thay đổi trong lần chạy đó).

    Compile time constant là loại giá trị cố định được tạo ra ngay từ lúc biên dịch code. Khi chương trình chạy, giá trị này giữ nguyên như khi nó được tạo ra (khi biên dịch). Dù bao nhiêu lần chạy, giá trị này vẫn giữ như vậy.

    Một cách khác để hình dung về compile time constant là: khi gặp khai báo loại constant này, thực chất compiler sẽ tự động copy giá trị của nó tới những nơi cần sử dụng! Việc này có tác dụng giống hệt như khi lập trình viên tự mình copy giá trị (thay vì khai báo và sử dụng hằng).

    Điều này dẫn đến sự khác biệt khi tham chiếu tới hằng từ một class khác:

    • Nếu sử dụng runtime constant, khi class chứa định nghĩa hằng bị biên dịch lại, class sử dụng hằng không bị ảnh hưởng.
    • Nếu sử dụng compile time constant, khi class chứa định nghĩa hằng bị biên dịch lại, class sử dụng hằng vẫn chứa giá trị cũ!

    Để class sử dụng hằng cập nhật giá trị mới, bạn phải biên dịch lại nó. Điều này rất dễ hiểu: khi biên dịch lại, compiler mới copy giá trị mới sang.

    Trong Kotlin, val dùng để khai báo runtime constant, const val dùng để khai báo compile time constant.

    Nếu bạn biết C#: val của Kotlin tương tự readonly trong C# (runtime constant), và const val của Kotlin tương tự const của C# (compile time constant).

    Kết luận

    Trong bài học này chúng ta đã làm quen với biến, giá trị, hằng, và kiểu dữ liệu trong Kotlin:

    • Kotlin là một ngôn ngữ định kiểu tĩnh và định kiểu mạnh;
    • Do đó, khai báo biến/giá trị/hằng đều phải kèm theo chỉ định kiểu;
    • Và kiểu dữ liệu của một biến là cố định sau khi được định nghĩa;
    • Giá trị là một loại biến chỉ đọc, còn gọi là runtime constant;
    • Hằng là giá trị cố định từ khi dịch, gọi là compile time constant;
    • Kotlin khuyến khích sử dụng giá trị thay cho biến nếu được.
    • Giá trị được sử dụng phổ biến với lập trình hàm.

    + Nếu bạn thấy site hữu ích, trước khi rời đi hãy giúp đỡ site bằng một hành động nhỏ để site có thể phát triển và phục vụ bạn tốt hơn.
    + Nếu bạn thấy bài viết hữu ích, hãy giúp chia sẻ tới mọi người.
    + Nếu có thắc mắc hoặc cần trao đổi thêm, mời bạn viết trong phần thảo luận cuối trang.
    Cảm ơn bạn!

    Theo dõi
    Thông báo của
    guest

    1 Thảo luận
    Cũ nhất
    Mới nhất
    Phản hồi nội tuyến
    Xem tất cả bình luận
    congtu

    Hay quá! Cảm ơn tác giả