Lớp học lập trình này nằm trong khóa học về Kotlin dành cho lập trình viên. Bạn sẽ nhận được nhiều giá trị nhất từ khóa học này nếu bạn làm việc qua các lớp học lập trình theo trình tự. Tùy thuộc vào kiến thức của mình, bạn có thể đọc lướt một số phần. Khóa học này dành cho những lập trình viên biết ngôn ngữ hướng đối tượng và muốn học Kotlin.
Giới thiệu
Trong lớp học lập trình này, bạn sẽ tìm hiểu khái niệm cơ bản về ngôn ngữ lập trình Kotlin: loại dữ liệu, toán tử, biến, cấu trúc kiểm soát và biến có thể có giá trị null và biến không thể có giá trị null. Khóa học này dành cho những lập trình viên biết ngôn ngữ hướng đối tượng và muốn học Kotlin.
Thay vì xây dựng một ứng dụng mẫu duy nhất, các bài học trong khóa học này được thiết kế để trang bị cho bạn kiến thức nhưng hãy độc lập với nhau để có thể đọc lướt các phần mà bạn quen thuộc. Nhiều ví dụ sử dụng chủ đề thủy cung để liên kết chúng với nhau. Và nếu bạn muốn xem toàn bộ câu chuyện về thủy cung, hãy xem khóa học Kotlin Bootcamp dành cho lập trình viên Udacity.
Kiến thức bạn cần có
- Cách tạo dự án trong IntelliJ IDEA
- Cách mở và thực thi mã trong REPL của Kotlin (Vòng lặp Read-Eval-Print) trong IntelliJ IDEA (Công cụ > Kotlin > Kotlin REPL)
Kiến thức bạn sẽ học được
- Cách sử dụng các loại dữ liệu, toán tử và biến Kotlin
- Cách làm việc với giá trị boolean và điều kiện
- Sự khác biệt giữa biến không thể có giá trị null và biến có thể có giá trị null
- Cách mảng, danh sách và vòng lặp hoạt động trong Kotlin
Bạn sẽ thực hiện
- Làm việc với Kotlin REPL để tìm hiểu kiến thức cơ bản về Kotlin
Trong nhiệm vụ này, bạn tìm hiểu về các toán tử và các loại bằng ngôn ngữ lập trình Kotlin.
Bước 1: Khám phá các toán tử số
- Mở IntelliJ IDEA nếu chưa mở.
- Để mở Kotlin REPL, hãy chọn Tools > Kotlin > Kotlin REPL.
Cũng giống như các ngôn ngữ khác, Kotlin sử dụng +
, -
, *
và /
để cộng, trừ, thời gian và phân chia. Kotlin cũng hỗ trợ nhiều loại số, chẳng hạn như Int
, Long
, Double
và Float
.
- Nhập các biểu thức sau trong REPL. Để xem kết quả, hãy nhấn
Control+Enter
(Command+Enter
trên máy Mac) sau mỗi máy.
1+1 ⇒ res8: kotlin.Int = 2 53-3 ⇒ res9: kotlin.Int = 50 50/10 ⇒ res10: kotlin.Int = 5 1.0/2.0 ⇒ res11: kotlin.Double = 0.5 2.0*3.5 ⇒ res12: kotlin.Double = 7.0
Lưu ý rằng kết quả của phép toán sẽ giữ nguyên loại toán hạng, vì vậy, 1/2 = 0, nhưng 1,0/2,0 = 0,5.
- Hãy thử một số biểu thức kết hợp số nguyên và số thập phân khác nhau.
6*50 ⇒ res13: kotlin.Int = 300 6.0*50.0 ⇒ res14: kotlin.Double = 300.0 6.0*50 ⇒ res15: kotlin.Double = 300.0
- Gọi một số phương thức trên số. Kotlin lưu giữ các số ở dạng nguyên thủy, nhưng cho phép bạn gọi phương thức cho các số đó như thể đó là đối tượng.
2.times(3) ⇒ res5: kotlin.Int = 6 3.5.plus(4) ⇒ res8: kotlin.Double = 7.5 2.4.div(2) ⇒ res9: kotlin.Double = 1.2
Bước 2: Thực hành sử dụng các loại
Kotlin không ngầm chuyển đổi giữa các loại số, vì vậy, bạn không thể chỉ định trực tiếp giá trị ngắn cho biến dài hoặc Byte
cho Int
. Điều này là do việc chuyển đổi số ngầm là nguồn phổ biến của các lỗi trong chương trình. Bạn luôn có thể chỉ định giá trị thuộc các loại khác nhau bằng cách truyền.
- Để xem một số lần truyền có thể xảy ra, hãy xác định một biến thuộc loại
Int
trong REPL.
val i: Int = 6
- Tạo một biến mới, sau đó nhập tên biến ở trên, theo sau là
.to
.
val b1 = i.to
IntelliJ IDEA sẽ hiển thị danh sách các khả năng hoàn thành có thể thực hiện. Tính năng tự động hoàn thành này hoạt động với mọi biến thể và đối tượng thuộc bất kỳ loại nào.
- Chọn
toByte()
từ danh sách, sau đó in biến.
val b1 = i.toByte()
println(b1)
⇒ 6
- Gán một giá trị
Byte
cho các biến thuộc nhiều loại.
val b2: Byte = 1 // OK, literals are checked statically
println(b2)
⇒ 1
val i1: Int = b2
⇒ error: type mismatch: inferred type is Byte but Int was expected
val i2: String = b2
⇒ error: type mismatch: inferred type is Byte but String was expected
val i3: Double = b2
⇒ error: type mismatch: inferred type is Byte but Double was expected
- Đối với bài tập đã trả về lỗi, hãy thử truyền bài tập.
val i4: Int = b2.toInt() // OK!
println(i4)
⇒ 1
val i5: String = b2.toString()
println(i5)
⇒ 1
val i6: Double = b2.toDouble()
println(i6)
⇒ 1.0
- Để giúp các hằng số dài dễ đọc hơn, Kotlin cho phép bạn đặt dấu gạch dưới trong các số ở vị trí phù hợp với bạn. Hãy thử nhập các hằng số khác nhau.
val oneMillion = 1_000_000 val socialSecurityNumber = 999_99_9999L val hexBytes = 0xFF_EC_DE_5E val bytes = 0b11010010_01101001_10010100_10010010
Bước 3: Tìm hiểu giá trị của các loại biến
Kotlin hỗ trợ 2 loại biến: dễ thay đổi và không thay đổi. Với val
, bạn có thể chỉ định một giá trị một lần. Nếu cố chỉ định lại giá trị nào đó, bạn sẽ gặp lỗi. Với var
, bạn có thể chỉ định một giá trị, rồi thay đổi giá trị đó trong chương trình vào lúc khác.
- Hãy xác định các biến bằng cách sử dụng
val
vàvar
, sau đó chỉ định các giá trị mới cho các biến đó.
var fish = 1
fish = 2
val aquarium = 1
aquarium = 2
⇒ error: val cannot be reassigned
Bạn có thể chỉ định một giá trị cho fish
, sau đó chỉ định một giá trị mới cho thuộc tính này vì giá trị đó được xác định bằng var
. Việc cố chỉ định một giá trị mới cho aquarium
sẽ gây ra lỗi vì biến này được xác định bằng val
.
Loại mà bạn lưu trữ ở dạng biến sẽ được dự đoán khi trình biên dịch có thể tìm ra loại dựa trên ngữ cảnh. Nếu muốn, bạn luôn có thể chỉ định rõ loại của một biến bằng cách dùng ký hiệu dấu hai chấm.
- Xác định một số biến và chỉ định loại rõ ràng.
var fish: Int = 12
var lakes: Double = 2.5
Sau khi bạn hoặc trình biên dịch chỉ định một loại, bạn không thể thay đổi loại đó, nếu không sẽ gặp lỗi.
Bước 4: Tìm hiểu về chuỗi
Các chuỗi trong Kotlin hoạt động giống hệt chuỗi trong bất kỳ ngôn ngữ lập trình nào khác sử dụng "
cho chuỗi và '
cho ký tự đơn lẻ. Bạn có thể ghép các chuỗi bằng toán tử +
. Bạn có thể tạo mẫu chuỗi bằng cách kết hợp chuỗi với các giá trị; tên $
variable
được thay thế bằng văn bản đại diện cho giá trị. Đây được gọi là phép nội suy biến.
- Tạo một mẫu chuỗi.
val numberOfFish = 5
val numberOfPlants = 12
"I have $numberOfFish fish" + " and $numberOfPlants plants"
⇒ res20: kotlin.String = I have 5 fish and 12 plants
- Tạo mẫu chuỗi có biểu thức. Giống như trong các ngôn ngữ khác, giá trị có thể là kết quả của một biểu thức. Hãy dùng dấu ngoặc nhọn
{}
để xác định biểu thức.
"I have ${numberOfFish + numberOfPlants} fish and plants"
⇒ res21: kotlin.String = I have 17 fish and plants
Trong nhiệm vụ này, bạn tìm hiểu về boolean và kiểm tra các điều kiện bằng ngôn ngữ lập trình Kotlin. Giống như các ngôn ngữ khác, Kotlin có giá trị boolean và toán tử boolean, ví dụ như nhỏ hơn, bằng, lớn hơn, v.v. (<
, ==
, >
, !=
, <=
, >=
).
- Viết câu lệnh
if
/else
.
val numberOfFish = 50
val numberOfPlants = 23
if (numberOfFish > numberOfPlants) {
println("Good ratio!")
} else {
println("Unhealthy ratio")
}
⇒ Good ratio!
- Hãy thử dùng một dải ô trong câu lệnh
if
. Trong Kotlin, điều kiện mà bạn kiểm tra cũng có thể sử dụng phạm vi.
val fish = 50
if (fish in 1..100) {
println(fish)
}
⇒ 50
- Viết một
if
với nhiều trường hợp. Đối với các điều kiện phức tạp hơn, hãy dùng logic và&&
cùng logic hoặc||
. Giống như trong các ngôn ngữ khác, bạn có thể gặp nhiều trường hợp khi sử dụngelse if
.
if (numberOfFish == 0) {
println("Empty tank")
} else if (numberOfFish < 40) {
println("Got fish!")
} else {
println("That's a lot of fish!")
}
⇒ That's a lot of fish!
- Hãy thử dùng câu lệnh
when
. Có một cách hữu hiệu hơn để viết loạt câu lệnhif
/else if
/else
đó trong Kotlin, sử dụng câu lệnhwhen
, tương tự như câu lệnhswitch
trong các ngôn ngữ khác. Các điều kiện trong câu lệnhwhen
cũng có thể sử dụng phạm vi.
when (numberOfFish) {
0 -> println("Empty tank")
in 1..39 -> println("Got fish!")
else -> println("That's a lot of fish!")
}
⇒ That's a lot of fish!
Trong nhiệm vụ này, bạn sẽ tìm hiểu về các biến có thể có giá trị null và biến không thể có giá trị null. Các lỗi lập trình liên quan đến biến null chính là nguồn gốc của vô số lỗi. Kotlin tìm cách giảm số lỗi bằng việc đưa các biến không thể có giá trị null vào.
Bước 1: Tìm hiểu về tính chất rỗng
Theo mặc định, các biến không thể là null
.
- Khai báo một
Int
và chỉ địnhnull
cho hàm đó.
var rocks: Int = null
⇒ error: null can not be a value of a non-null type Int
- Sử dụng toán tử dấu chấm hỏi,
?
, sau loại để cho biết rằng một biến có thể có giá trị null. Khai báo mộtInt?
và chỉ địnhnull
cho hàm đó.
var marbles: Int? = null
Khi bạn có các loại dữ liệu phức tạp, chẳng hạn như một danh sách:
- Bạn có thể cho phép các thành phần trong danh sách có giá trị null.
- Bạn có thể cho phép danh sách có giá trị null, nhưng nếu danh sách không có giá trị null thì các thành phần sẽ không thể có giá trị null.
- Bạn có thể cho phép cả danh sách và thành phần có giá trị null.
Danh sách và một số loại dữ liệu phức tạp khác được đề cập trong một tác vụ sau này.
Bước 2: Tìm hiểu về? và toán tử ?:
Bạn có thể thử nghiệm null
bằng toán tử ?
, điều này giúp bạn không phải viết nhiều câu lệnh if
/else
.
- Viết một đoạn mã dài hơn để kiểm tra xem biến
fishFoodTreats
có phải lànull
hay không. Sau đó, giảm dần biến đó.
var fishFoodTreats = 6
if (fishFoodTreats != null) {
fishFoodTreats = fishFoodTreats.dec()
}
- Bây giờ, hãy xem cách viết của Kotlin, sử dụng toán tử
?
.
var fishFoodTreats = 6
fishFoodTreats = fishFoodTreats?.dec()
- Bạn cũng có thể tạo chuỗi kiểm tra biến null với toán tử
?:
. Hãy xem ví dụ sau:
fishFoodTreats = fishFoodTreats?.dec() ?: 0
Giá trị rút gọn của "nếu fishFoodTreats
không phải là null
, hãy giảm dần và sử dụng; nếu không, hãy sử dụng giá trị sau ?:
, là 0." Nếu fishFoodTreats
là null
, thì quá trình đánh giá sẽ dừng lại và phương thức dec()
sẽ không được gọi.
Lưu ý về con trỏ rỗng
Nếu bạn thực sự thích NullPointerExceptions
, Kotlin sẽ cho phép bạn lưu giữ giá trị đó. Toán tử xác nhận không có giá trị null, !!
(double-bang), sẽ chuyển đổi mọi giá trị thành loại không có giá trị null và gửi một ngoại lệ nếu giá trị đó là null
.
val len = s!!.length // throws NullPointerException if s is null
Trong nhiệm vụ này, bạn tìm hiểu về các mảng và danh sách, cũng như tìm hiểu các cách tạo vòng lặp trong ngôn ngữ lập trình Kotlin.
Bước 1: Tạo danh sách
Danh sách là một loại cơ bản của Kotlin và tương tự như các danh sách bằng các ngôn ngữ khác.
- Khai báo một danh sách bằng
listOf
và in ra. Bạn không thể thay đổi danh sách này.
val school = listOf("mackerel", "trout", "halibut")
println(school)
⇒ [mackerel, trout, halibut]
- Khai báo một danh sách có thể thay đổi được bằng
mutableListOf
. Xóa một mục.
val myList = mutableListOf("tuna", "salmon", "shark")
myList.remove("shark")
⇒ res36: kotlin.Boolean = true
Phương thức remove()
trả về true
khi xóa thành công mục đã chuyển.
Bước 2: Tạo mảng
Giống như các ngôn ngữ khác, Kotlin có các mảng. Khác với các danh sách trong Kotlin, có phiên bản có thể thay đổi và không thể thay đổi, Array
không có phiên bản có thể thay đổi. Sau khi bạn tạo một mảng, kích thước của mảng sẽ là cố định. Bạn không thể thêm hoặc xóa các thành phần, trừ khi dùng cách sao chép sang một mảng mới.
Quy tắc về việc sử dụng val
và var
giống với mảng và danh sách.
- Hãy khai báo một mảng chuỗi bằng lệnh
arrayOf
. Sử dụng tiện ích mảngjava.util.Arrays.toString()
để in ra.
val school = arrayOf("shark", "salmon", "minnow")
println(java.util.Arrays.toString(school))
⇒ [shark, salmon, minnow]
- Mảng được khai báo bằng
arrayOf
không có loại được liên kết với các phần tử, vì vậy, bạn có thể kết hợp các loại. Điều này rất hữu ích. Hãy khai báo một mảng bằng nhiều loại.
val mix = arrayOf("fish", 2)
- Bạn cũng có thể khai báo mảng có một loại cho tất cả phần tử. Hãy khai báo một mảng số nguyên bằng cách dùng
intArrayOf()
. nhưng cũng có các trình tạo hoặc hàm tạo thực thể tương ứng cho các mảng thuộc loại khác.
val numbers = intArrayOf(1,2,3)
- Kết hợp 2 mảng với toán tử
+
.
val numbers = intArrayOf(1,2,3)
val numbers3 = intArrayOf(4,5,6)
val foo2 = numbers3 + numbers
println(foo2[5])
=> 3
- Thử các kết hợp khác nhau của mảng và danh sách lồng nhau. Giống như trong các ngôn ngữ khác, bạn có thể lồng các mảng và danh sách. Tức là, khi bạn đặt một mảng vào một mảng, bạn sẽ có một mảng chứa các mảng – chứ không phải một mảng phẳng gồm nội dung của hai mảng. Các thành phần của một mảng cũng có thể là danh sách và các thành phần của danh sách cũng có thể là các mảng.
val numbers = intArrayOf(1, 2, 3)
val oceans = listOf("Atlantic", "Pacific")
val oddList = listOf(numbers, oceans, "salmon")
println(oddList)
⇒ [[I@89178b4, [Atlantic, Pacific], salmon]
Phần tử đầu tiên là numbers
là Array
. Khi bạn không sử dụng tiện ích mảng để in, Kotlin sẽ in địa chỉ thay vì nội dung của mảng.
- Một tính năng đẹp mắt của Kotlin là bạn có thể khởi chạy các mảng bằng mã thay vì khởi tạo các mảng đó thành 0. Hãy thử ví dụ sau:
val array = Array (5) { it * 2 }
println(java.util.Arrays.toString(array))
⇒ [0, 2, 4, 6, 8]
Mã khởi chạy giữa các dấu ngoặc nhọn, {}
. Trong mã, it
đề cập đến chỉ mục mảng, bắt đầu bằng 0.
Bước 3: Tạo vòng lặp
Bây giờ, bạn đã có danh sách và mảng, việc lặp qua các thành phần sẽ hoạt động như bạn mong đợi.
- Tạo một mảng. Dùng một vòng lặp
for
để lặp lại mảng và in các thành phần.
val school = arrayOf("shark", "salmon", "minnow")
for (element in school) {
print(element + " ")
}
⇒ shark salmon minnow
- Trong Kotlin, bạn có thể lặp theo các thành phần và chỉ mục cùng một lúc. Hãy thử ví dụ sau:
for ((index, element) in school.withIndex()) {
println("Item at $index is $element\n")
}
⇒ Item at 0 is shark Item at 1 is salmon Item at 2 is minnow
- Hãy thử nhiều kích cỡ bước và phạm vi. Bạn có thể chỉ định phạm vi số hoặc phạm vi ký tự, theo thứ tự bảng chữ cái. Và giống như trong các ngôn ngữ khác, bạn không phải tiến lên 1 bước. Bạn có thể lùi lại bằng
downTo
.
for (i in 1..5) print(i)
⇒ 12345
for (i in 5 downTo 1) print(i)
⇒ 54321
for (i in 3..6 step 2) print(i)
⇒ 35
for (i in 'd'..'g') print (i)
⇒ defg
- Dùng thử một số vòng lặp. Giống như các ngôn ngữ khác, Kotlin có vòng lặp
while
, vòng lặpdo...while
, toán tử++
và--
. Kotlin cũng có vòng lặprepeat
.
var bubbles = 0
while (bubbles < 50) {
bubbles++
}
println("$bubbles bubbles in the water\n")
do {
bubbles--
} while (bubbles > 50)
println("$bubbles bubbles in the water\n")
repeat(2) {
println("A fish is swimming")
}
⇒ 50 bubbles in the water 49 bubbles in the water A fish is swimmingA fish is swimming
Kotlin rất giống với các ngôn ngữ khác khi dùng những khái niệm cơ bản như toán tử, danh sách và vòng lặp, nhưng có một số điểm khác biệt quan trọng.
Các tính năng sau có thể khác trong Kotlin so với những tính năng mà bạn quen dùng trong các ngôn ngữ khác:
- Không thể chuyển đổi các loại Kotlin dưới dạng ngầm ẩn – hãy dùng tính năng truyền.
- Chỉ có thể chỉ định các biến được khai báo bằng
val
một lần. - Theo mặc định, các biến Kotlin không thể có giá trị null. Dùng
?
để làm cho các biến có thể có giá trị null. - Với Kotlin, bạn có thể lặp theo chỉ mục và các thành phần của một mảng cùng lúc trong một vòng lặp
for
.
Các cấu trúc lập trình Kotlin sau đây tương tự như các cấu trúc trong ngôn ngữ khác:
- Mảng và danh sách có thể có một loại hoặc loại kết hợp.
- Mảng và danh sách có thể được lồng vào nhau.
- Bạn có thể tạo vòng lặp bằng
for
,while
,do
/while
vàrepeat
. - Câu lệnh
when
là phiên bản của Kotlin tuyên bốswitch
, nhưngwhen
linh hoạt hơn.
Tài liệu về Kotlin
Nếu bạn muốn biết thêm thông tin về bất kỳ chủ đề nào trong khóa học này hoặc nếu bạn gặp khó khăn, https://kotlinlang.org là điểm khởi đầu tốt nhất của bạn.
- Chuyển đổi loại rõ ràng
- Định nghĩa biến
- Mẫu chuỗi
- Giá trị có thể bỏ qua
- Danh sách
- Mảng
if
,when
,for
,while
- Toán tử
?:
(Elvis) - Toán tử
!!
Hướng dẫn về Kotlin
Trang web https://try.kotlinlang.org có các hướng dẫn phong phú được gọi là Kotlin Koans, một biên dịch viên dựa trên web và một bộ tài liệu tham khảo đầy đủ có các ví dụ.
Khóa học Udacity
Để xem khóa học Udacity về chủ đề này, hãy xem Kotlin Bootcamp dành cho lập trình viên.
IntelliJ IDEA
Bạn có thể tìm thấy tài liệu về IntelliJ IDEA trên trang web của JetBrains.
Phần này liệt kê các bài tập về nhà có thể được giao cho học viên đang làm việc qua lớp học lập trình này trong khóa học do người hướng dẫn tổ chức. Người hướng dẫn có thể làm những việc sau:
- Giao bài tập về nhà nếu được yêu cầu.
- Trao đổi với học viên cách nộp bài tập về nhà.
- Chấm điểm bài tập về nhà.
Người hướng dẫn có thể sử dụng những đề xuất này ít hay nhiều tùy ý. Do đó, họ có thể thoải mái giao bất kỳ bài tập về nhà nào khác mà họ cảm thấy phù hợp.
Nếu bạn đang tự mình làm việc qua lớp học lập trình này, hãy thoải mái sử dụng các bài tập về nhà này để kiểm tra kiến thức của bạn.
Trả lời những câu hỏi này
Câu hỏi 1
Danh sách nào sau đây khai báo danh sách các chuỗi không thể thay đổi?
▢ val school = arrayOf("shark", "salmon", "minnow")
▢ var school = arrayOf("shark", "salmon", "minnow")
▢ val school = listOf("shark", "salmon", "minnow")
▢ val school = mutableListOf("shark", "salmon", "minnow")
Câu hỏi 2
Mã đầu ra của mã sau sẽ là gì?for (i in 3..8 step 2) print(i)
▢ 345678
▢ 468
▢ 38
▢ 357
Câu hỏi 3
Mục đích của dấu chấm hỏi trong mã này là gì?var rocks: Int? = 3
▢ Loại biến rocks
không cố định.
▢ Biến rocks
có thể được đặt thành rỗng.
▢ Không thể đặt biến rocks
thành giá trị null.
▢Biến rocks
không được khởi tạo ngay lập tức.
Chuyển sang bài học tiếp theo:
Để biết thông tin tổng quan về khóa học, bao gồm cả các đường liên kết đến các lớp học lập trình khác, hãy xem "Kotlin Bootcamp dành cho lập trình viên: Chào mừng bạn đến với khóa học này?