fbpx

Kotlin là gì? đây là một ngôn ngữ lập trình hiện đại được duy trì như một dự án mã nguồn mở của JetBrains, một công ty hàng đầu thế giới về IDE. Trở lại năm 2011, JetBrains sử dụng ngôn ngữ Java trong toàn bộ các dự án của mình, tuy nhiên trong quá trình phát triển, java phát sinh một số bất cập về nhiều mặt( vấn đề bản quyền, sự phụ thuộc vào Orcale, ngôn ngữ java đã có tuổi đời rất lâu) nên yêu cầu tìm kiếm một ngôn ngữ lập trình mới để giúp họ lập trình hiệu quả hơn là yêu cầu cần thiết. Cuối cùng, họ quyết định tạo ra một ngôn ngữ lập trình mới có tên Kotlin.

Trong những năm qua Kotlin đã phát triển để trở thành một ngôn ngữ lập trình thay thế cho Java, cho phép các nhà phát triển Java dễ dàng nâng cấp lên một ngôn ngữ mới biểu cảm hơn. Không chỉ vậy, tháng 5 năm 2017 Google đã công bố Kotlin sẽ là một ngôn ngữ được hỗ trợ chính thức trên nền tảng Android. Với sự hổ trợ từ JetBrains và Google, không có gì ngạc nhiên khi Kotlin lại có được sự nổi tiếng lớn như vậy.

Xem thêm lịch sử hình thành Kotlin tại đây

Sử dụng Kotlin

Để bắt đầu với Kotlin, điều đầu tiên bạn cần là một nơi nào đó để viết mã. Nơi dễ nhất để viết mã Kotlin là trang web try.kotlinlang.org . Nó cung cấp rất nhiều ví dụ thực hành Kotlin và nếu bạn đăng nhập, bạn thậm chí có thể tạo các chương trình của riêng mình và các đoạn mã chương trình đó sẽ được lưu trữ trên cloud.

Bạn cũng có thể thực hành bằng cách sử dụng Kotlin trong một IDE như IntelliJ IDEA. Để tạo một dự án Kotlin trong IntelliJ IDEA, hãy làm theo các bước sau .Nếu bạn muốn sử dụng Kotlin trong một dự án Android, hãy xem trang này để được hướng dẫn.

Các khái niệm cơ bản trong ngôn ngữ lập trình Kotlin

Định nghĩa biến:

Để tạo một biến trong Kotlin, chúng ta sử dụng từ khóa var.

var greeting :  String  =  "Hello World!"

Mã này yêu cầu máy tính tạo một biến mới có tên là ‘greeting’ sẽ có kiểu String và chứa văn bản, “Hello World!”. Ngoài cách khai bao một biến tường minh với kiểu dữ liệu đi kèm, Kotlin cũng hỗ trợ cách khai báo không tường minh cho một biến bất kì, ví dụ trên được viết lại thành đoàn code khai báo đơn giản sau:

var greeting =  "Hello world!"  // Kiểu được suy ra là một Chuỗi

Khi bạn đã tạo một biến, bạn có thể dễ dàng sửa đổi nó bằng cách đặt lại giá trị lưu trữ cho nó bằng cách sau:

var greeting =  "Hello World!" 
greeting =  "Hello Kotlin!"

Đôi khi bạn muốn tạo một biến để lưu trữ một giá trị nào đó bất biến trong toàn bộ vòng đời của chương trình, các biến này lưu trữ một hằng số và không được phép thay đổi. Trong Kotlin có hai loại  định nghĩa biến: có thể thay đổikhông thay đổi đượcMutable có nghĩa là biến CÓ THỂ THAY ĐỔI được giá trị và Immutable là loại biến KHÔNG THỂ THAY ĐỔI giá trị. Để tạo biến có thể thay đổi, chúng tôi sử dụng từ khóa var như chúng tôi đã làm. Tuy nhiên, để tạo ra biến không thay đổi, chúng ta cần sử dụng từ khóa val.

Nếu chúng ta thay đổi khai báo từ var sang val trong ví dụ trên thì dòng thứ hai sẽ cho chúng ta một lỗi trình biên dịch bởi vì chúng ta không còn được phép thay đổi biến “greetting” của mình:

val greeting =  "Hello word!" 
greeting =  "Hello Kotlin!"  // Lỗi trình biên dịch: không thể gán lại val

Xâu dữ liệu chuỗi

Trong ví dụ trên chúng ta đã sử dụng kiểu String. Hãy xem cách chúng ta có thể kết hợp hai Strings lại với nhau bằng cách sử dụng toán tử +.

val language = "Kotlin"
val creator = "JetBrains"
val description = language + " is created by " + creator
// description = "Kotlin is created by JetBrains"

Kết hợp các chuỗi với nhau như thế này được gọi là nối. Đôi khi sử dụng toán tử + để nối có thể hơi trừu tượng với một số người, do đó Kotlin hổ trợ việc tạo chuỗi thông qua templates – “chuỗi mẫu”. Chuỗi mẫu cho phép  sử dụng các biến bên trong dấu ngoặc kép bằng cách mở đầu biến bằng $:

val releaseDate = "July 2011"
val releaseString = "Kotlin was released in $releaseDate"
// releaseString = "Kotlin was released in July 2011"

Kết quả releaseString chứa giá trị của releaseDate cùng với phần còn lại của String. Chúng ta có thể đã thực hiện được điều tương tự với toán tử +, nhưng cách này dễ dàng hơn và dễ đọc hơn. Đối với những ví dụ này, chúng tôi đã sử dụng từ khóa val có nghĩa là chúng tôi không thể thay đổi Chuỗi sau khi tạo. Hãy nhớ rằng, nếu bạn muốn có thể sửa đổi một biến sau khi tạo nó, chỉ cần sử dụng từ khóa var.

Kiểu dữ liệu Number trong Kotlin

Cùng với kiểu dữ liệu xâu ký tự Strings Kotlin cũng cung cấp một số kiểu số. Điều quan trọng nhất là Int, Long, Float và Double. Int và Long được sử dụng cho các số nguyên, trong khi Float và Double được sử dụng cho các giá trị thập phân. Ngoài ra, Int và Float sử dụng 32 bit để lưu trữ các giá trị của chúng, trong khi Long và Double sử dụng 64. Vì vậy, nếu bạn cần lưu trữ một số thực sự lớn, bạn sẽ sử dụng Long hoặc Double thay vì Int hoặc Float.

Theo mặc định, Kotlin quy ước bất kỳ giá trị số nguyên nào sẽ được nhập là Int và bất kỳ giá trị thập phân nào sẽ được nhập thành Double:

val num1 = 42 // Int
val num2 = 3.14 // Double

Nếu bạn muốn khai báo một số dưới dạng Float hoặc Long, bạn cần thêm ‘f’ hoặc ‘L’ vào cuối số:

val num1 = 42.toFloat() // Float
val num2 = num1.toDouble() // Double

Bạn cũng có thể chuyển đổi giữa các loại số khác nhau bằng cách sử dụng các hàm toType:

val distToMoon = 92_960_000 // miles (inferred type Int)

Lưu ý rằng bởi việc giới hạn bộ nhớ của từng kiểu dữ liệu số, nên khi chuyển một số kiểu Long sang Int có thể bạn sẽ gặp trường hợp đầy bộ nhớ lưu trữ của biến kiểu Int khiến kết quả lưu trữ khác với giá trị ban đầu.

Kiểu dữ liệu luận lý Booleans

Kotlin cũng chứa một kiểu Boolean. Các kiểu Boolean được sử dụng để biểu diễn giá trị true hoặc false. Để đặt biến Boolean, hãy sử dụng từ khóa đúng hoặc sai:

val isGoodDay = true
val isBadDay = false

Kiểu dữ liệu Nullability

Trong hầu hết các ngôn ngữ, khi bạn tạo một biến nhưng không đặt nó bằng một cái gì đó, nó nhận được một giá trị NULL, có thể được coi là không bằng bất cứ thứ gì. NULL giá trị gây ra các vấn đề trong nhiều chương trình khi chương trình cố gắng làm một cái gì đó với một giá trị NULL. Ví dụ:

// java code
String address;
println(address);

Đoạn mã trên tạo ra một biến String có tên là ‘address’ và sau đó cố gắng in ra địa chỉ trước khi nó được thiết lập. Điều này dẫn đến một NullPointerException và treo chương trình. Trong Kotlin, các lỗi này sẽ được trình biên dịch thông báo đến với người lập trình, và chỉ khi giải quyết vấn đề này chương trình mới có thể biên dịch thành công, điều này hạn chế việc nhảy ra các thông báo lỗi khi chương trình được thực thi.

val x : Int // Lỗi - biến phải được khởi tạo

Ngoài ra, bạn không thể chỉ thiết lập một biến bằng NULL. Trước tiên, bạn cần đánh dấu loại của biến đó là nullable bằng cách sử dụng dấu chấm hỏi:

val x : Int =  null  // Lỗi - null không thể là giá trị cho kiểu không null Int 
val x : Int ?  =  null  // OK 
val y :  String  =  null  // Lỗi - null không thể là một giá trị cho kiểu không null String 
val y :  String ?  =  null  // OK

Ngoài ra còn có một vài toán tử để giúp chúng ta đối phó với các giá trị NULL. Hãy xem ví dụ sau:

val name: String? = null
println(name.length) // Error - Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?

Trong ví dụ trên chúng ta khai báo một biến “name” với kiểu dữ liệu là null Sau đó in chiều dài của chuỗi ký tự được lưu trữ trong biến “name”  Tuy nhiên, vì Kotlin biết rằng  giá trị trong “name” có thể là NULL, nó cho chúng ta thấy một lỗi. Để khắc phục lỗi này, chúng ta có hai lựa chọn, chúng ta có thể khẳng định một trong hai (!!) tên đó không phải là NULL, hoặc chúng ta có thể sử dụng những gì được biết đến như một lời gọi an toàn (?).

Sử dụng một lời gọi an toàn (? Ví dụ như tên .length) có nghĩa là nếu tên là NULL, thay vì cố gắng để có được độ dài của một đối tượng NULL và gây ra một lỗi, nó sẽ chỉ trả về NULL:

val name: String? = null
println(name?.length) // prints “null”

Bạn sẽ sử dụng một xác nhận không null (!!) khi bạn biết chắc chắn rằng một biến nullable không thể là null, như được hiển thị ở đây:

var name: String? = null
name = "Treehouse"
println(name!!.length) // prints "9"

Kiểu dữ liệu Collections:

Collection là kiểu dữ liệu lưu trữ nhiều giá trị cùng kiểu dữ liệu. Mỗi giá trị trong collection đều được đánh số chỉ mục, để truy cập các giá trị trong một collection chúng ta thường truy cập trực tiếp thông qua đánh số chỉ mục của từng giá trị.

Kiểu dữ liệu array

Một mảng là một tập hợp các mục được lập chỉ mục mà tất cả đều có cùng một loại. Để tạo một mảng, chúng ta sử dụng hàm arrayOf:

val cardNames: Array = arrayOf("Jack", "Queen", "King")

Để truy cập một mục từ mảng, chúng tôi sử dụng chỉ mục (bắt đầu từ 0) của mục chúng tôi muốn truy cập. Vì vậy, để truy cập vào mục đầu tiên trong mảng chúng ta sẽ sử dụng:

val firstCard = cardNames [ 0 ]  // firstCard = "Jack"

Để thay thế một mục hiện có trong mảng, chỉ cần chỉ mục con mục đó và đặt nó bằng một giá trị khác:

cardNames [ 0 ]  =  "Ace"

Mảng có kích thước cố định; khi được tạo, không có cách nào để thêm hoặc xóa các mục khỏi một mảng. Nếu bạn muốn thêm và xóa các mục khỏi bộ sưu tập, hãy thử sử dụng kiểu Lists – Danh sách

Kiểu Lists – Danh sách

Trong Kotlin có hai loại List: List và MutableList. Lớp List hoạt động khá giống với một Array, ngoại trừ việc bạn không thể sửa đổi các mục trong một List. Tuy nhiên, lớp MutableList cho phép chúng ta sửa đổi các mục trong danh sách cũng như thêm và xóa các mục. Để tạo một MutableList mới, chúng tôi sử dụng hàm mutableListOf:

val cards = mutableListOf ( "Jack" , "Queen" , "King" )

Sử dụng MutableList cung cấp cho chúng tôi một số tùy chọn để thêm / xóa các mục:

cards.add("Ace") // Jack, Queen, King, Ace
cards.remove("Jack") // Queen, King, Ace
cards.clear() // empty list
cards.addAll("Jack", "Queen", "King", "Ace") // Jack, Queen, King, Ace

Kiểu dữ liệu Maps:

Loại bộ sưu tập quan trọng cuối cùng là Bản đồ (và MutableMap). Bản đồ cho phép chúng tôi lưu trữ các cặp khóa-giá trị và truy cập các giá trị bằng cách cung cấp các khóa.

Ví dụ: nếu chúng tôi muốn lưu trữ thông tin số cùng với dữ liệu thẻ của mình, chúng tôi có thể tạo một bản đồ như sau:

val cards = mapOf("Jack" to 11, "Queen" to 12, "King" to 13)

Ở trên, chúng tôi đã chỉ định tên thẻ là các khóa và đã ánh xạ chúng với các giá trị tương ứng của chúng. Ở đây chúng ta đang sử dụng các khóa String và các giá trị Int, nhưng chúng ta không bị giới hạn chỉ với các chuỗi và Ints; bạn có thể sử dụng bất kỳ loại nào trong Bản đồ. Để truy cập vào một thẻ cụ thể, chỉ cần sử dụng phím để truy lục giá trị:

val jackValue = cards["Jack"] // 11

Nếu chúng ta muốn thêm các mục vào thẻ của chúng ta Bản đồ, trước tiên chúng ta sẽ cần phải thay đổi nó thành một MutableMap, và sau đó chúng ta chỉ có thể thiết lập các giá trị mới:

val cards = mutableMapOf("Jack" to 11, "Queen" to 12, "King" to 13)
cards["Ace"] = 1

Bạn cũng có thể sử dụng hàm toMutableMap để biến Map thành một MutableMap:

val cards = mapOf("Jack" to 11, "Queen" to 12, "King" to 13)
val mutableCards = cards.toMutableMap()
mutableCards["Ace"] = 1

Các câu lệnh điều khiển trong Kotlin

Vòng lặp looping

Trong Kotlin có hai loại vòng lặp: forwhile. Bạn có thể sử dụng vòng lặp for để duyệt collection như sau:

val cards = mutableListOf("Jack", "Queen", "King")
for (card in cards) {
    println(card)
}

Hàm println trong Kotlin sẽ in ra màn hình giá trị của bất kỳ thứ gì nằm giữa các dấu ngoặc đơn. Vì vậy, mã này in mỗi thẻ trên một dòng mới:

Jack
Queen
King

Vòng lặp for cũng có thể được sử dụng để lặp qua một dãy số. Để in các số từ 1 đến 10, bạn có thể sử dụng các số sau cho vòng lặp.

for (i in 1..10) {
   println(i)
}

Tuy nhiên, nếu bạn muốn lặp lại từ 10 đến 1, thay vì hai dấu chấm, bạn sẽ cần toán tử downTo:

for (i in 10 downTo 1) {
   println(i)
}

Bạn cũng có thể sử dụng vòng lặp for để lặp qua Bản đồ. Mã này lặp qua thẻ Bản đồ và in ra tên và giá trị của mỗi thẻ:

val cards = mapOf("Jack" to 11, "Queen" to 12, "King" to 13)
for ((name, value) in cards) {
    println("$name, $value")
}

Ngoài các vòng lặp, Kotlin cũng cung cấp một vòng lặp while. Trong khi các vòng lặp được sử dụng để lặp lại cho đến khi một điều kiện nhất định được đáp ứng:

while (stillDownloading) {
   println("Downloading…")
}

Mã này sẽ in “Đang tải xuống…” cho đến khi biến “stillDownloading” vẫn còn là false.

Câu lệnh If – If Expression

Hầu hết các ngôn ngữ đều có một câu lệnh if, nhưng trong Kotlin chúng ta có một biểu thức if (nó trả về một giá trị). Vì vậy, ngoài việc sử dụng nếu các câu lệnh theo cách thông thường:

val a = 5
val b = 3
var aIsBigger = false
if (a > b) {
   aIsBigger = true
} else {
   aIsBigger = false
}

Chúng ta cũng có thể sử dụng chúng để thiết lập các biến của chúng ta (cho phép chúng ta sử dụng một val thay vì một var!):

val aIsBigger =  if  ( a > b )  { 
    true 
}  else  { 
    false 
}

Không chỉ vậy, ta có thể viết lại đoạn code trên với chỉ 1 dòng bằng cách dùng biểu thức if và các dầu ngoặc.

val aIsBigger = if (a > b) true else false

Câu lệnh điều khiển When – When Expression

Thay vì sử cung cấp câu lệnh switch như các ngôn ngữ khác, Kotlin sử dụng biểu thức When để thay thế cho việc sử dụng nhiều hàm if để so sánh giá trị.

when (cardInt) {
    11 -> println("Jack")
    12 -> println("Queen")
    13 -> println("King")
}

Với ví dụ dưới đây bạn sẽ thấy việc sử dụng câu lệnh when sẽ hợp lý hơn khi dùng câu lệnh if.

val cardName = when (cardInt) {
    11 -> "Jack"
    12 -> "Queen"
    13 -> "King"
    else -> "Other"
}

Ghi chú: mặc dù việc kết hợp nhiều câu lệnh if thành một câu lệnh when đem lại giá trị rất lớn trong quá trình rút ngắn code, tuy nhiên bạn cần lưu ý miền giá trị cần được so sánh và đặt giá trị trả về mặc định nếu giá trị cần so sánh có giá trị chưa được định nghĩa trong biểu thức when. Sử dụng từ khóa else kết hợp với trong when sẽ giúp bạn đặt giá trị mặc định trả về cho các trường hợp không được định nghĩa so sánh.

Định nghĩa hàm trong Kotlin – functions in Kotlin

Các hàm là các khối mã mà bạn có thể sử dụng để đơn giản hóa các chương trình của mình. Ví dụ, println là một hàm nhận trong một biến và in giá trị của nó vào màn hình. Trong Kotlin, chúng ta có thể tạo các chức năng của riêng mình bằng cách sử dụng từ khóa ‘fun’ và sau đó cung cấp tên cho hàm:

fun printJack ( )  { 
   println ( "Jack" ) 
}

Chúng ta cũng có thể thêm các tham số vào hàm của chúng ta:

fun printCard(cardName: String, cardValue: Int) {
   println("$cardName = $cardValue")
}

Nếu chúng ta muốn, thay vì in ra thẻ, chúng ta có thể trả về nó như một đối tượng String:

fun getCardString(cardName: String, cardValue: Int): String {
   return("$cardName = $cardValue")
}

Một điều thú vị khác về Kotlin là khi bạn thấy mình viết một hàm chỉ với một câu lệnh return, bạn có thể bỏ qua các dấu ngoặc “{}” và trả về ngay kết quả chỉ với dấu “=”

fun getCardString(cardName: String, cardValue: Int): String = "$cardName = $cardValue"

Kotlin thậm chí có thể nội suy ra rằng kiểu trả về sẽ là một String, với cách viết rút gọn sau:

fun getCardString(cardName: String, cardValue: Int) = "$cardName = $cardValue"

Kết luận:

Nếu bạn đã xem và thực hiện các ví dụ trong bài viết này thì, xin chúc mừng bạn! Bây giờ bạn đã có cơ sở tốt để bắt đầu xây dựng một số kiến ​​thức nghiêm túc về Kotlin.

About the author

Kevin Dang

Hey there! My name is Kevin Dang, I am website, software, mobile app develop, web admin system. Expert living in Hồ Chí Minh (Việt Nam). I am very interested in digital marketing with: SEO, Facebook, Google Ads ... This blog is where I will share the experiences, techniques and knowledge I have learned.