Kotlin Bootcamp for Programmers 5.1: Extensions

Codelab นี้เป็นส่วนหนึ่งของหลักสูตร Kotlin Bootcamp สำหรับโปรแกรมเมอร์ คุณจะได้รับประโยชน์สูงสุดจากหลักสูตรนี้หากทำตาม Codelab ตามลำดับ คุณอาจข้ามบางส่วนได้ ทั้งนี้ขึ้นอยู่กับความรู้ของคุณ หลักสูตรนี้เหมาะสำหรับโปรแกรมเมอร์ที่รู้จักภาษาเชิงวัตถุและต้องการเรียนรู้ Kotlin

บทนำ

ในโค้ดแล็บนี้ คุณจะได้รู้จักฟีเจอร์ต่างๆ ที่มีประโยชน์ใน Kotlin ซึ่งรวมถึงคู่ คอลเล็กชัน และฟังก์ชันส่วนขยาย

บทเรียนในหลักสูตรนี้ได้รับการออกแบบมาเพื่อสร้างความรู้ของคุณ แต่จะมีความเป็นอิสระจากกันในระดับหนึ่งเพื่อให้คุณข้ามส่วนที่คุณคุ้นเคยได้ แทนที่จะสร้างแอปตัวอย่างเพียงแอปเดียว ตัวอย่างหลายรายการใช้ธีมตู้ปลาเพื่อเชื่อมโยงตัวอย่างต่างๆ เข้าด้วยกัน และหากต้องการดูเรื่องราวทั้งหมดของตู้ปลา ให้ดูหลักสูตร Kotlin Bootcamp for Programmers ของ Udacity

สิ่งที่คุณควรทราบอยู่แล้ว

  • ไวยากรณ์ของฟังก์ชัน คลาส และเมธอด Kotlin
  • วิธีทำงานกับ REPL (Read-Eval-Print Loop) ของ Kotlin ใน IntelliJ IDEA
  • วิธีสร้างคลาสใหม่ใน IntelliJ IDEA และเรียกใช้โปรแกรม

สิ่งที่คุณจะได้เรียนรู้

  • วิธีทำงานกับคู่และสามสิ่ง
  • ข้อมูลเพิ่มเติมเกี่ยวกับคอลเล็กชัน
  • การกำหนดและการใช้ค่าคงที่
  • การเขียนฟังก์ชันส่วนขยาย

สิ่งที่คุณต้องดำเนินการ

  • ดูข้อมูลเกี่ยวกับคู่ สามสิ่ง และแฮชแมปใน REPL
  • ดูวิธีต่างๆ ในการจัดระเบียบค่าคงที่
  • เขียนฟังก์ชันส่วนขยายและพร็อพเพอร์ตี้ส่วนขยาย

ในงานนี้ คุณจะได้เรียนรู้เกี่ยวกับคู่และสามสิ่ง รวมถึงการแยกโครงสร้าง Pair และ Triple เป็นคลาสข้อมูลที่สร้างไว้ล่วงหน้าสำหรับรายการทั่วไป 2 หรือ 3 รายการ ซึ่งอาจมีประโยชน์ เช่น ในการทำให้ฟังก์ชันแสดงผลค่ามากกว่า 1 ค่า

สมมติว่าคุณมีListปลา และฟังก์ชัน isFreshWater() เพื่อตรวจสอบว่าปลาเป็นปลาน้ำจืดหรือปลาน้ำเค็ม List.partition() จะแสดงผล 2 รายการ รายการหนึ่งมีสินค้าที่มีเงื่อนไขเป็น true และอีกรายการหนึ่งมีสินค้าที่มีเงื่อนไขเป็น false

val twoLists = fish.partition { isFreshWater(it) }
println("freshwater: ${twoLists.first}")
println("saltwater: ${twoLists.second}")

ขั้นตอนที่ 1: สร้างคู่และสาม

  1. เปิด REPL (Tools > Kotlin > Kotlin REPL)
  2. สร้างคู่โดยเชื่อมโยงอุปกรณ์กับสิ่งที่ใช้ จากนั้นพิมพ์ค่า คุณสร้างคู่ได้โดยสร้างนิพจน์ที่เชื่อมต่อค่า 2 ค่า เช่น สตริง 2 รายการ ด้วยคีย์เวิร์ด to จากนั้นใช้ .first หรือ .second เพื่ออ้างอิงถึงแต่ละค่า
val equipment = "fish net" to "catching fish"
println("${equipment.first} used for ${equipment.second}")
⇒ fish net used for catching fish
  1. สร้างทริปเปิลและพิมพ์ด้วย toString() จากนั้นแปลงเป็นรายการด้วย toList() คุณสร้างทริปเปิลโดยใช้ Triple() ที่มีค่า 3 ค่า ใช้ .first, .second และ .third เพื่ออ้างอิงถึงแต่ละค่า
val numbers = Triple(6, 9, 42)
println(numbers.toString())
println(numbers.toList())
⇒ (6, 9, 42)
[6, 9, 42]

ตัวอย่างข้างต้นใช้ประเภทเดียวกันสำหรับทุกส่วนของคู่หรือสามส่วน แต่ไม่จำเป็นต้องทำเช่นนั้น โดยส่วนต่างๆ อาจเป็นสตริง ตัวเลข หรือรายการ เช่น แม้แต่คู่หรือสามสิ่งอื่น

  1. สร้างคู่โดยที่ส่วนแรกของคู่เป็นคู่เอง
val equipment2 = ("fish net" to "catching fish") to "equipment"
println("${equipment2.first} is ${equipment2.second}\n")
println("${equipment2.first.second}")
⇒ (fish net, catching fish) is equipment
⇒ catching fish

ขั้นตอนที่ 2: แยกโครงสร้างคู่และสามสิ่ง

การแยกคู่และสามสิ่งออกเป็นส่วนๆ เรียกว่าการแยกโครงสร้าง กำหนดคู่หรือสามสิ่งให้กับตัวแปรจำนวนที่เหมาะสม แล้ว Kotlin จะกำหนดค่าของแต่ละส่วนตามลำดับ

  1. แยกโครงสร้างคู่และพิมพ์ค่า
val equipment = "fish net" to "catching fish"
val (tool, use) = equipment
println("$tool is used for $use")
⇒ fish net is used for catching fish
  1. แยกโครงสร้างของทริปเปิลและพิมพ์ค่า
val numbers = Triple(6, 9, 42)
val (n1, n2, n3) = numbers
println("$n1 $n2 $n3")
⇒ 6 9 42

โปรดทราบว่าการแยกโครงสร้างคู่และสามสิ่งทำงานเหมือนกับในคลาสข้อมูล ซึ่งเราได้กล่าวถึงใน Codelab ก่อนหน้านี้

ในงานนี้ คุณจะได้ดูข้อมูลเพิ่มเติมเกี่ยวกับคอลเล็กชัน ซึ่งรวมถึงรายการ และคอลเล็กชันประเภทใหม่ นั่นคือ Hash Map

ขั้นตอนที่ 1: ดูข้อมูลเพิ่มเติมเกี่ยวกับรายการ

  1. เราได้แนะนำรายการและรายการที่เปลี่ยนแปลงได้ไปแล้วในบทเรียนก่อนหน้า ซึ่งเป็นโครงสร้างข้อมูลที่มีประโยชน์มาก ดังนั้น Kotlin จึงมีฟังก์ชันในตัวหลายฟังก์ชันสำหรับรายการ ดูรายการฟังก์ชันบางส่วนนี้สำหรับรายการ ดูรายการทั้งหมดได้ในเอกสารประกอบ Kotlin สำหรับ List และ MutableList

การทำงาน

Purpose

add(element: E)

เพิ่มรายการลงในลิสต์ที่เปลี่ยนแปลงได้

remove(element: E)

นำรายการออกจากลิสต์ที่เปลี่ยนแปลงได้

reversed()

ส่งคืนสำเนาของรายการที่มีองค์ประกอบในลำดับย้อนกลับ

contains(element: E)

แสดงผล true หากลิสต์มีรายการ

subList(fromIndex: Int, toIndex: Int)

แสดงส่วนของรายการจากดัชนีแรกจนถึงดัชนีที่สอง (ไม่รวมดัชนีที่สอง)

  1. สร้างรายการตัวเลขและเรียกใช้ sum() ใน REPL ซึ่งเป็นการสรุปองค์ประกอบทั้งหมด
val list = listOf(1, 5, 3, 4)
println(list.sum())
⇒ 13
  1. สร้างรายการสตริงและหาผลรวมของรายการ
val list2 = listOf("a", "bbb", "cc")
println(list2.sum())
⇒ error: none of the following functions can be called with the arguments supplied:
  1. หากองค์ประกอบไม่ใช่สิ่งที่ List ทราบวิธีรวมโดยตรง เช่น สตริง คุณสามารถระบุวิธีรวมได้โดยใช้ .sumBy() กับฟังก์ชัน Lambda เช่น เพื่อรวมตามความยาวของแต่ละสตริง ชื่อเริ่มต้นของอาร์กิวเมนต์ Lambda คือ it และในที่นี้ it หมายถึงแต่ละองค์ประกอบของรายการเมื่อมีการข้ามรายการ
val list2 = listOf("a", "bbb", "cc")
println(list2.sumBy { it.length })
⇒ 6
  1. คุณทำสิ่งต่างๆ ได้อีกมากมายด้วยรายการ วิธีหนึ่งในการดูฟังก์ชันที่มีให้ใช้งานคือการสร้างรายการใน IntelliJ IDEA เพิ่มจุด แล้วดูรายการเติมข้อความอัตโนมัติในเคล็ดลับเครื่องมือ ซึ่งใช้ได้กับออบเจ็กต์ทุกรายการ ลองใช้กับรายการ

  1. เลือก listIterator() จากรายการ จากนั้นดูรายการด้วยคำสั่ง for แล้วพิมพ์องค์ประกอบทั้งหมดโดยคั่นด้วยช่องว่าง
val list2 = listOf("a", "bbb", "cc")
for (s in list2.listIterator()) {
    println("$s ")
}
⇒ a bbb cc

ขั้นตอนที่ 2: ลองใช้แฮชแมป

ใน Kotlin คุณสามารถแมปแทบทุกอย่างกับทุกอย่างได้โดยใช้ hashMapOf() แฮชแมปคล้ายกับรายการคู่ โดยค่าแรกจะทำหน้าที่เป็นคีย์

  1. สร้างแฮชแมปที่ตรงกับอาการ ซึ่งเป็นคีย์ และโรคของปลา ซึ่งเป็นค่า
val cures = hashMapOf("white spots" to "Ich", "red sores" to "hole disease")
  1. จากนั้นคุณจะเรียกค่าโรคตามคีย์อาการได้โดยใช้ get() หรือแม้แต่เครื่องหมายวงเล็บเหลี่ยม [] ที่สั้นกว่า
println(cures.get("white spots"))
⇒ Ich
println(cures["red sores"])
⇒ hole disease
  1. ลองระบุอาการที่ไม่ได้อยู่ในแผนที่
println(cures["scale loss"])
⇒ null

หากไม่มีคีย์ในแผนที่ การพยายามส่งคืนโรคที่ตรงกันจะส่งคืน null การไม่มีรายการที่ตรงกันสำหรับคีย์ที่เป็นไปได้อาจเป็นเรื่องปกติ ทั้งนี้ขึ้นอยู่กับข้อมูลแผนที่ สำหรับกรณีเช่นนี้ Kotlin มีฟังก์ชัน getOrDefault()

  1. ลองค้นหาคีย์ที่ไม่มีรายการที่ตรงกันโดยใช้ getOrDefault()
println(cures.getOrDefault("bloating", "sorry, I don't know"))
⇒ sorry, I don't know

หากต้องการทำมากกว่าแค่การคืนค่า Kotlin มีฟังก์ชัน getOrElse() ให้

  1. เปลี่ยนโค้ดเพื่อใช้ getOrElse() แทน getOrDefault()
println(cures.getOrElse("bloating") {"No cure for this"})
⇒ No cure for this

ระบบจะเรียกใช้โค้ดใดก็ตามที่อยู่ระหว่างวงเล็บปีกกา {} แทนที่จะแสดงค่าเริ่มต้นธรรมดา ในตัวอย่าง else จะแสดงสตริง แต่คุณอาจใช้ฟังก์ชันนี้เพื่อค้นหาหน้าเว็บที่มีวิธีรักษาและแสดงผลได้

คุณสามารถสร้าง mutableMapOf ได้เช่นเดียวกับ mutableListOf แผนที่ที่เปลี่ยนแปลงได้ช่วยให้คุณใส่และนำรายการออกได้ Mutable หมายถึงเปลี่ยนแปลงได้ ส่วน immutable หมายถึงเปลี่ยนแปลงไม่ได้

  1. สร้างแผนที่สินค้าคงคลังที่แก้ไขได้ โดยแมปสตริงอุปกรณ์กับจำนวนสินค้า สร้างโดยใส่ตาข่ายจับปลาไว้ข้างใน จากนั้นเพิ่มที่ขัดถัง 3 อันลงในสินค้าคงคลังด้วย put() แล้วนำตาข่ายจับปลาออกด้วย remove()
val inventory = mutableMapOf("fish net" to 1)
inventory.put("tank scrubber", 3)
println(inventory.toString())
inventory.remove("fish net")
println(inventory.toString())
⇒ {fish net=1, tank scrubber=3}{tank scrubber=3}

ในงานนี้ คุณจะได้เรียนรู้เกี่ยวกับค่าคงที่ใน Kotlin และวิธีต่างๆ ในการจัดระเบียบค่าคงที่

ขั้นตอนที่ 1: ดูข้อมูลเกี่ยวกับ const กับ val

  1. ลองสร้างค่าคงที่ตัวเลขใน REPL ใน Kotlin คุณสามารถสร้างค่าคงที่ระดับบนสุดและกำหนดค่าให้ได้ในเวลาคอมไพล์โดยใช้ const val
const val rocks = 3

ระบบจะกำหนดค่าและคุณจะเปลี่ยนค่าไม่ได้ ซึ่งคล้ายกับการประกาศ val ปกติ const val กับ val แตกต่างกันอย่างไร ค่าสำหรับ const val จะกำหนดในเวลาคอมไพล์ ส่วนค่าสำหรับ val จะกำหนดในระหว่างการดำเนินการโปรแกรม ซึ่งหมายความว่าฟังก์ชันสามารถกำหนดค่า val ได้ในรันไทม์

ซึ่งหมายความว่าคุณกำหนดค่าจากฟังก์ชันให้กับ val ได้ แต่กำหนดให้กับ const val ไม่ได้

val value1 = complexFunctionCall() // OK
const val CONSTANT1 = complexFunctionCall() // NOT ok

นอกจากนี้ const val ยังใช้ได้เฉพาะที่ระดับบนสุดและในคลาส Singleton ที่ประกาศด้วย object เท่านั้น ไม่ใช่กับคลาสปกติ คุณสามารถใช้สิ่งนี้เพื่อสร้างไฟล์หรือออบเจ็กต์ Singleton ที่มีเฉพาะค่าคงที่ และนำเข้าได้ตามต้องการ

object Constants {
    const val CONSTANT2 = "object constant"
}
val foo = Constants.CONSTANT2

ขั้นตอนที่ 2: สร้างออบเจ็กต์คู่

Kotlin ไม่มีแนวคิดค่าคงที่ระดับคลาส

หากต้องการกำหนดค่าคงที่ภายในคลาส คุณต้องรวมค่าคงที่ไว้ในออบเจ็กต์คู่ที่ประกาศด้วยคีย์เวิร์ด companion โดยพื้นฐานแล้วออบเจ็กต์คู่คือออบเจ็กต์ Singleton ภายในคลาส

  1. สร้างคลาสที่มีออบเจ็กต์คู่ซึ่งมีค่าคงที่สตริง
class MyClass {
    companion object {
        const val CONSTANT3 = "constant in companion"
    }
}

ความแตกต่างพื้นฐานระหว่างออบเจ็กต์เสริมกับออบเจ็กต์ปกติมีดังนี้

  • ระบบจะเริ่มต้นออบเจ็กต์คู่จากตัวสร้างแบบคงที่ของคลาสที่ประกอบด้วยออบเจ็กต์คู่ ซึ่งหมายความว่าระบบจะสร้างออบเจ็กต์คู่เมื่อสร้างออบเจ็กต์
  • ระบบจะเริ่มต้นออบเจ็กต์ปกติแบบเลื่อนเวลาเมื่อมีการเข้าถึงออบเจ็กต์นั้นเป็นครั้งแรก ซึ่งก็คือเมื่อมีการใช้ออบเจ็กต์เป็นครั้งแรก

ยังมีอีกมาก แต่สิ่งที่คุณต้องรู้ในตอนนี้คือการห่อหุ้มค่าคงที่ในคลาสในออบเจ็กต์คู่

ในงานนี้ คุณจะได้เรียนรู้เกี่ยวกับการขยายลักษณะการทำงานของคลาส การเขียนฟังก์ชันยูทิลิตีเพื่อขยายลักษณะการทำงานของคลาสเป็นเรื่องปกติมาก Kotlin มีไวยากรณ์ที่สะดวกสำหรับการประกาศฟังก์ชันยูทิลิตีเหล่านี้ ซึ่งก็คือฟังก์ชันส่วนขยาย

ฟังก์ชันส่วนขยายช่วยให้คุณเพิ่มฟังก์ชันลงในคลาสที่มีอยู่ได้โดยไม่ต้องเข้าถึงซอร์สโค้ด เช่น คุณอาจประกาศในไฟล์ Extensions.kt ซึ่งเป็นส่วนหนึ่งของแพ็กเกจ ซึ่งไม่ได้เป็นการแก้ไขคลาสจริงๆ แต่ช่วยให้คุณใช้สัญกรณ์แบบจุดเมื่อเรียกฟังก์ชันในออบเจ็กต์ของคลาสนั้นได้

ขั้นตอนที่ 1: เขียนฟังก์ชันส่วนขยาย

  1. ยังคงทำงานใน REPL ให้เขียนฟังก์ชันส่วนขยายอย่างง่าย hasSpaces() เพื่อตรวจสอบว่าสตริงมีช่องว่างหรือไม่ ชื่อฟังก์ชันจะมีคำนำหน้าเป็นคลาสที่ฟังก์ชันทำงาน ภายในฟังก์ชัน this จะอ้างอิงถึงออบเจ็กต์ที่เรียกใช้ และ it จะอ้างอิงถึงตัววนซ้ำในการเรียกใช้ find()
fun String.hasSpaces(): Boolean {
    val found = this.find { it == ' ' }
    return found != null
}
println("Does it have spaces?".hasSpaces())
⇒ true
  1. คุณสามารถลดความซับซ้อนของฟังก์ชัน hasSpaces() ได้ ไม่จำเป็นต้องมี this อย่างชัดเจน และสามารถลดฟังก์ชันให้เหลือเพียงนิพจน์เดียวและแสดงผลได้ จึงไม่จำเป็นต้องมีเครื่องหมายปีกกา {} รอบนิพจน์นั้นด้วย
fun String.hasSpaces() = find { it == ' ' } != null

ขั้นตอนที่ 2: ดูข้อจำกัดของส่วนขยาย

ฟังก์ชันส่วนขยายจะมีสิทธิ์เข้าถึงเฉพาะ API สาธารณะของคลาสที่ขยาย เข้าถึงตัวแปรที่privateไม่ได้

  1. ลองเพิ่มฟังก์ชันส่วนขยายลงในพร็อพเพอร์ตี้ที่ทำเครื่องหมาย private
class AquariumPlant(val color: String, private val size: Int)

fun AquariumPlant.isRed() = color == "red"    // OK
fun AquariumPlant.isBig() = size > 50         // gives error
⇒ error: cannot access 'size': it is private in 'AquariumPlant'
  1. พิจารณาโค้ดด้านล่างและดูว่าโค้ดจะพิมพ์อะไรออกมา
open class AquariumPlant(val color: String, private val size: Int)

class GreenLeafyPlant(size: Int) : AquariumPlant("green", size)

fun AquariumPlant.print() = println("AquariumPlant")
fun GreenLeafyPlant.print() = println("GreenLeafyPlant")

val plant = GreenLeafyPlant(size = 10)
plant.print()
println("\n")
val aquariumPlant: AquariumPlant = plant
aquariumPlant.print()  // what will it print?
⇒ GreenLeafyPlant
AquariumPlant

plant.print() รูปอัด GreenLeafyPlant คุณอาจคาดหวังให้ aquariumPlant.print() พิมพ์ GreenLeafyPlant ด้วย เนื่องจากมีการกำหนดค่าเป็น plant แต่ประเภทจะได้รับการแก้ไขในเวลาคอมไพล์ ดังนั้น AquariumPlant จะได้รับการพิมพ์

ขั้นตอนที่ 3: เพิ่มพร็อพเพอร์ตี้ส่วนขยาย

นอกจากฟังก์ชันส่วนขยายแล้ว Kotlin ยังให้คุณเพิ่มพร็อพเพอร์ตี้ส่วนขยายได้ด้วย เช่นเดียวกับฟังก์ชันส่วนขยาย คุณต้องระบุคลาสที่ต้องการขยาย ตามด้วยจุด แล้วตามด้วยชื่อพร็อพเพอร์ตี้

  1. ขณะที่ยังทำงานใน REPL ให้เพิ่มพร็อพเพอร์ตี้ส่วนขยาย isGreen ไปยัง AquariumPlant ซึ่งก็คือ true หากสีเป็นสีเขียว
val AquariumPlant.isGreen: Boolean
   get() = color == "green"

คุณเข้าถึงพร็อพเพอร์ตี้ isGreen ได้เหมือนกับพร็อพเพอร์ตี้ปกติ เมื่อเข้าถึง ระบบจะเรียกใช้ Getter สำหรับ isGreen เพื่อรับค่า

  1. พิมพ์พร็อพเพอร์ตี้ isGreen สำหรับตัวแปร aquariumPlant และสังเกตผลลัพธ์
aquariumPlant.isGreen
⇒ res4: kotlin.Boolean = true

ขั้นตอนที่ 4: รู้จักตัวรับที่กำหนดให้เป็น Null ได้

คลาสที่คุณขยายเรียกว่าตัวรับ และคุณทำให้คลาสดังกล่าวเป็น Nullable ได้ หากทำเช่นนั้น thisตัวแปรที่ใช้ในเนื้อหาอาจเป็น null ดังนั้นโปรดทดสอบเพื่อดูว่าตัวแปรดังกล่าวทำงานได้หรือไม่ คุณอาจต้องการใช้ตัวรับที่อนุญาตให้เป็น Null ได้หากคาดว่าผู้เรียกจะต้องการเรียกใช้เมธอดส่วนขยายในตัวแปรที่อนุญาตให้เป็น Null ได้ หรือหากต้องการระบุลักษณะการทำงานเริ่มต้นเมื่อใช้ฟังก์ชันกับ null

  1. ยังคงทำงานใน REPL ให้กำหนดเมธอด pull() ที่ใช้ตัวรับที่อนุญาตให้เป็น Null โดยจะระบุด้วยเครื่องหมายคำถาม ? หลังประเภทและก่อนจุด ในส่วนเนื้อหา คุณสามารถทดสอบว่า this ไม่ใช่ null ได้โดยใช้เครื่องหมายคำถาม-จุด-ใช้ ?.apply.
fun AquariumPlant?.pull() {
   this?.apply {
       println("removing $this")
   }
}

val plant: AquariumPlant? = null
plant.pull()
  1. ในกรณีนี้ จะไม่มีเอาต์พุตเมื่อคุณเรียกใช้โปรแกรม เนื่องจาก plant คือ null ระบบจึงไม่เรียกใช้ println() ด้านใน

ฟังก์ชันส่วนขยายมีประสิทธิภาพมาก และไลบรารีมาตรฐานของ Kotlin ส่วนใหญ่จะได้รับการติดตั้งใช้งานเป็นฟังก์ชันส่วนขยาย

ในบทเรียนนี้ คุณได้เรียนรู้เพิ่มเติมเกี่ยวกับคอลเล็กชัน ค่าคงที่ รวมถึงได้สัมผัสถึงประสิทธิภาพของฟังก์ชันและพร็อพเพอร์ตี้ส่วนขยาย

  • คุณใช้คู่และสามสิ่งเพื่อแสดงค่ามากกว่า 1 ค่าจากฟังก์ชันได้ เช่น
    val twoLists = fish.partition { isFreshWater(it) }
  • Kotlin มีฟังก์ชันที่มีประโยชน์มากมายสำหรับ List เช่น reversed(), contains() และ subList()
  • HashMap ใช้เพื่อแมปคีย์กับค่าได้ เช่น
    val cures = hashMapOf("white spots" to "Ich", "red sores" to "hole disease")
  • ประกาศค่าคงที่ขณะคอมไพล์โดยใช้คีย์เวิร์ด const คุณสามารถวางไว้ที่ระดับบนสุด จัดระเบียบในออบเจ็กต์ Singleton หรือวางไว้ในออบเจ็กต์คู่
  • ออบเจ็กต์คู่คือออบเจ็กต์ Singleton ภายในคำจำกัดความของคลาส ซึ่งกำหนดด้วยคีย์เวิร์ด companion
  • ฟังก์ชันและพร็อพเพอร์ตี้ของส่วนขยายจะเพิ่มฟังก์ชันการทำงานให้กับคลาสได้ เช่น
    fun String.hasSpaces() = find { it == ' ' } != null
  • ตัวรับที่กำหนดให้เป็น Null ได้ช่วยให้คุณสร้างส่วนขยายในคลาสที่อาจเป็น null ได้ คุณสามารถใช้โอเปอเรเตอร์ ?. ร่วมกับ apply เพื่อตรวจสอบ null ก่อนที่จะเรียกใช้โค้ด เช่น
    this?.apply { println("removing $this") }

เอกสารประกอบ Kotlin

หากต้องการข้อมูลเพิ่มเติมเกี่ยวกับหัวข้อใดก็ตามในหลักสูตรนี้ หรือหากคุณติดขัด https://kotlinlang.org คือจุดเริ่มต้นที่ดีที่สุด

บทแนะนำ Kotlin

เว็บไซต์ https://try.kotlinlang.org มีบทแนะนำที่สมบูรณ์ซึ่งเรียกว่า Kotlin Koans, ตัวแปลภาษาบนเว็บ และชุดเอกสารอ้างอิงที่สมบูรณ์พร้อมตัวอย่าง

หลักสูตร Udacity

หากต้องการดูหลักสูตร Udacity ในหัวข้อนี้ โปรดดูค่ายฝึก Kotlin สำหรับโปรแกรมเมอร์

IntelliJ IDEA

เอกสารประกอบสำหรับ IntelliJ IDEA อยู่ในเว็บไซต์ของ JetBrains

ส่วนนี้แสดงรายการการบ้านที่เป็นไปได้สำหรับนักเรียน/นักศึกษาที่กำลังทำ Codelab นี้เป็นส่วนหนึ่งของหลักสูตรที่สอนโดยผู้สอน ผู้สอนมีหน้าที่ดำเนินการต่อไปนี้

  • มอบหมายการบ้านหากจำเป็น
  • สื่อสารกับนักเรียนเกี่ยวกับวิธีส่งงานที่ได้รับมอบหมาย
  • ให้คะแนนงานการบ้าน

ผู้สอนสามารถใช้คำแนะนำเหล่านี้ได้มากน้อยตามที่ต้องการ และควรมีอิสระในการมอบหมายการบ้านอื่นๆ ที่เห็นว่าเหมาะสม

หากคุณกำลังทำ Codelab นี้ด้วยตนเอง โปรดใช้แบบฝึกหัดเหล่านี้เพื่อทดสอบความรู้ของคุณ

ตอบคำถามต่อไปนี้

คำถามที่ 1

ข้อใดต่อไปนี้จะแสดงผลสำเนาของรายการ

add()

remove()

reversed()

contains()

คำถามที่ 2

ฟังก์ชันส่วนขยายใดต่อไปนี้ใน class AquariumPlant(val color: String, val size: Int, private val cost: Double, val leafy: Boolean) ที่จะทำให้เกิดข้อผิดพลาดของคอมไพเลอร์

fun AquariumPlant.isRed() = color == "red"

fun AquariumPlant.isBig() = size > 45

fun AquariumPlant.isExpensive() = cost > 10.00

fun AquariumPlant.isNotLeafy() = leafy == false

คำถามที่ 3

ข้อใดต่อไปนี้ไม่ใช่ที่ที่คุณกำหนดค่าคงที่ด้วย const val ได้

▢ ที่ระดับบนสุดของไฟล์

▢ ในชั้นเรียนปกติ

▢ ในออบเจ็กต์ Singleton

▢ ในออบเจ็กต์ร่วม

ไปยังบทเรียนถัดไป: 5.2 Generics

ดูภาพรวมของหลักสูตร รวมถึงลิงก์ไปยังโค้ดแล็บอื่นๆ ได้ที่ "Kotlin Bootcamp for Programmers: Welcome to the course"