12/08/2018, 16:29

Kotlin cơ bản - Bài 2: Biến và hằng

Qua bài trước, chúng ta đã tìm hiểu về các kiểu dữ liệu cơ bản trong Kotlin. Ở bài viết này, mình sẽ hướng dẫn các bạn về biến (variable) và hằng (constant) Trong quá trình học tập ở trường đối với các bậc trung học, chúng ta đã quá quen thuộc đối với biến. Chúng ta dùng các biến x , y huyền ...

Qua bài trước, chúng ta đã tìm hiểu về các kiểu dữ liệu cơ bản trong Kotlin. Ở bài viết này, mình sẽ hướng dẫn các bạn về biến (variable) và hằng (constant)

Trong quá trình học tập ở trường đối với các bậc trung học, chúng ta đã quá quen thuộc đối với biến. Chúng ta dùng các biến x, y huyền thoại để giải các bài toán bậc nhất, hệ phương trình, dùng các biến a, b, c để giải phương trình bậc 2, 3,... Đó đều là những ví dụ điển hình của biến trong lập trình. Tạo biến, gán giá trị cho biến giống như việc bạn đặt tên cho một quyển sách, đặt nickname cho một bạn trong lớp hay một con gấu bông,.... và những cái tên đó có thể thay đổi theo thời gian.

Hằng số là những giá trị cố định, bất biến theo thời gian, chúng ta không thể thay đổi nó một khi đã khai báo. Ví dụ: năm sinh của bạn, số PI = 3.14....

Khai báo

Trong Kotlin, để tạo một biến (có thể thay đổi giá trị sau này), ta dùng từ khóa var (viết tắt của variable)

// var [tênBiến]: [kiểuDữLiệu] = [giáTrịKhởiTạo]

// Ví dụ về khai báo đầy đủ
var fullName: String = "Hung Pham"

// Ví dụ về khai báo không có kiểu dữ liệu
// Kotlin sẽ lấy kiểu dữ liệu dựa vào giá trị truyền vào
var courseName = "Kotlin cơ bản"
var courseIndex = 1

Với hằng số (không thể thay đổi giá trị), ta dùng từ khóa val (viết tắt của value)

// val tênBiến : kiểuDữLiệu = giáTrịKhởiTạo

// Khai báo hằng không cần kiểu dữ liệu (vì 3.14 là kiểu Double)
val PI = 3.14

// Khai báo hằng không cần kiểu dữ liệu (1000 thuộc kiểu Int, nhưng 1000L là kiểu Long - xem lại bài trước)
// Dấu gạch chân chỉ để cho dev dễ đọc - xem lại bài trước
val aLongValue = 1_000L
val anotherLongValue: Long = 3000L

Null Safety

Một vấn đề vô cùng đau đầu đối với Java đó là NullPointerException. Nếu trong lúc code chúng ta không cẩn thận kiểm tra các trường hợp null, thì khi người dùng chạy chương trình mà gặp phải lỗi đó, phần mềm sẽ bị force close ngay lập tức, dẫn đến trải nghiệm người dùng bị kém đi.

Kotlin ra đời để tránh được những vấn đề đó bằng cách xác định biến có được phép null hay không ngay từ khi khai báo, cũng như chỉ ra biến có thể null ngay trong lúc code chứ không phải sau khi chương trình đã hoàn thành nữa. Và Kotlin cũng giúp bỏ qua những lệnh null mà không bị force close. Đó gọi là Null Safety.

Để khai báo một biến có thể null hay không, ta thêm dấu chấm hỏi (?) vào sau kiểu dữ liệu:

var canBeNull: String? = "SomeString" // Biến này có thể null
var cannotBeNull: String = "SomeString"

canBeNull = null // Không lỗi vì biến này có thể null
cannotBeNull = null // IDE sẽ báo lỗi ngay lập tức

Mỗi khi chúng ta gọi biến có thể null (nullable) mà chưa check null từ trước, bạn đều phải sử dụng 1 trong 2 kí tự ? hoặc !! để quyết định xem có chạy lệnh đó hay không.

// canBeNull?
// Nếu canBeNull có giá trị là null, chương trình sẽ bỏ qua 
// không chạy dòng lệnh này, ngược lại sẽ chạy nó
canBeNull = canBeNull?.toLowerCase()

// canBeNull!!
// Nếu canBeNull có giá trị là null, chương trình 
// sẽ dừng lại, báo lỗi như trong Java. 
// Chúng ta chỉ dùng nó khi biết chắc chắn rằng nó không null
canBeNull = canBeNull!!.toLowerCase()

Chúng ta cũng có thể check null từ trước bằng lệnh if (sẽ nói ở phần sau), và sau chúng ta. không cần phải dùng ? hoặc !! nữa

if (canBeNull !== null) {
    // Ở trong này, canBeNull sẽ chắc chắn không null, 
    // nên bạn không cần dùng ? hoặc !! nữa
    canBeNull = canBeNull.toLowerCase()
}

// Bên ngoài vẫn phải dùng như bình thường
canBeNull = canBeNull!!.toLowerCase()

Hoặc

if (canBeNull === null) return;

// Từ dưới này trở đi, canBeNull sẽ không thể null, 
// nên không cần dùng ? và !! nữa
canBeNull = canBeNull.toLowerCase()

Elvis Operator

Trong Java chúng ta hay check xem biến này có null không, nếu không thì gán vào, ngược lại thì gán giá trị mặc định

String someThing;

if (canBeNull !== null) {
    someThing = canBeNull;
} else {
    someThing = "some default string";
}

// Hoặc ngắn gọn hơn
someThing = canBeNull !== null ? canBeNull : "some default string"

Ở Kotlin có một cách khác ngắn gọn hơn rất nhiều:

var someThing = canBeNull ?: "some default string"

Dấu ?: này sẽ kiểm tra xem vế bên trái có null không. Nếu không null thì trả về chính vế trái, còn null thì trả về vế phải. Và ở đây chúng ta đã dùng biến someThing để hứng giá trị trả về đó. Rất tiện phải không?

0