0Pricing
Kotlin Academy · บทเรียน

lateinit และการเริ่มต้นแบบ Lazy

ใช้ lateinit กับพร็อพเพอร์ตีที่กำหนดค่าภายหลัง และใช้ by lazy สำหรับการคำนวณแบบเลื่อนเวลา

lateinit และการเริ่มต้นแบบ Lazy เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

เครื่องมือสองอย่างสำหรับการตั้งค่าภายหลัง

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

พื้นฐานของการเริ่มต้นภายหลัง

lateinit var เลื่อนการเริ่มต้นออกไป ตัวแปรต้องเป็น var ที่ไม่เป็นค่าว่างและไม่ใช่ชนิดพื้นฐาน หากเข้าถึงก่อนกำหนดค่า จะเกิด UninitializedPropertyAccessException

class Service {
    lateinit var name: String
    fun init(value: String) { name = value }
}
fun main() {
    val s = Service()
    s.init("MyService")
    println(s.name)
}

เหตุผลที่ใช้การเริ่มต้นภายหลัง

ใช้ lateinit สำหรับการฉีดการพึ่งพา ชุดข้อมูลสำหรับการทดสอบ หรือวงจรชีวิตที่เฟรมเวิร์กจัดการ เช่น มุมมอง Android และ bean ของ Spring ซึ่งการเริ่มต้นเกิดขึ้นนอกตัวสร้าง

class Repository {
    lateinit var db: String   // assigned later by DI framework
    fun query() = "querying $db"
}
fun main() {
    val r = Repository()
    r.db = "postgres://localhost"
    println(r.query())
}

การตรวจสอบการเริ่มต้น

คุณสามารถตรวจสอบว่าพร็อพเพอร์ตี lateinit ถูกกำหนดค่าแล้วหรือไม่ด้วย ::propName.isInitialized

class Foo {
    lateinit var bar: String
    fun status() = if (::bar.isInitialized) "set to $bar" else "unset"
}
fun main() {
    val f = Foo()
    println(f.status()) // unset
    f.bar = "hi"
    println(f.status())
}

ข้อจำกัดของการเริ่มต้นภายหลัง

คุณไม่สามารถใช้ lateinit กับชนิดพื้นฐาน เช่น Int หรือ Boolean ชนิดที่รับค่าว่างได้ หรือ val ได้ คอมไพเลอร์จะบังคับใช้กฎเหล่านี้

// VALID:
lateinit var name: String
// INVALID:
// lateinit var count: Int       // primitives not allowed
// lateinit val constant: String // val not allowed
// lateinit var maybe: String?   // nullable not allowed
fun main() { name = "ok"; println(name) }

พื้นฐานของการเริ่มต้นแบบขี้เกียจ

by lazy จะเลื่อนการเริ่มต้นของ val จนกว่าจะมีการเข้าถึงครั้งแรก แลมบ์ดาจะทำงานเพียงครั้งเดียวและผลลัพธ์จะถูกเก็บไว้ในแคช

val expensive: String by lazy {
    println("Computing...")
    "result"
}
fun main() {
    println(expensive) // Computing... then result
    println(expensive) // result (cached)
}

เหตุผลที่ใช้การเริ่มต้นแบบขี้เกียจ

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

class Config {
    val parsed: Map<String, String> by lazy {
        println("parsing config...")
        mapOf("host" to "localhost", "port" to "8080")
    }
}
fun main() {
    val c = Config()
    println("config object created — not parsed yet")
    println(c.parsed["host"]) // now parses
    println(c.parsed["port"]) // cached
}

โหมดความปลอดภัยของเธรดสำหรับการเริ่มต้นแบบขี้เกียจ

โดยค่าเริ่มต้น by lazy จะใช้ LazyThreadSafetyMode.SYNCHRONIZED ใช้ PUBLICATION สำหรับการเริ่มต้นที่ทำงานพร้อมกันได้ และใช้ NONE เพื่อประสิทธิภาพในโปรแกรมที่มีเธรดเดียว

val safe: String by lazy { "thread-safe" }
val fast: String by lazy(LazyThreadSafetyMode.NONE) { "fast, single-thread" }
fun main() {
    println(safe)
    println(fast)
}

การเริ่มต้นภายหลังเทียบกับการเริ่มต้นแบบขี้เกียจ

การเริ่มต้นภายหลัง: var ซึ่งกำหนดค่าจากภายนอก การเริ่มต้นแบบขี้เกียจ: val ซึ่งพร็อพเพอร์ตีคำนวณค่าเองเมื่อถูกเข้าถึงครั้งแรก

class Demo {
    lateinit var injected: String         // assigned by caller
    val computed: String by lazy { "computed once" }
}
fun main() {
    val d = Demo()
    d.injected = "from outside"
    println(d.injected)
    println(d.computed)
}

การอ่านพร็อพเพอร์ตีอื่นด้วยการเริ่มต้นแบบขี้เกียจ

พร็อพเพอร์ตีแบบขี้เกียจสามารถอ่านพร็อพเพอร์ตีอื่นที่เริ่มต้นไว้ก่อนแล้วและนำค่ามาประกอบกันได้

class User(val first: String, val last: String) {
    val fullName: String by lazy { "$first $last" }
}
fun main() {
    val u = User("Ada", "Lovelace")
    println(u.fullName)
}

รูปแบบการใช้งานจริง

ใช้การเริ่มต้นภายหลังสำหรับการฉีดการพึ่งพา และใช้การเริ่มต้นแบบขี้เกียจสำหรับสถานะที่ได้จากการคำนวณภายในคลาสเดียวกัน

class App {
    lateinit var config: Map<String, String>
    val host: String by lazy { config["host"] ?: "localhost" }
}
fun main() {
    val app = App()
    app.config = mapOf("host" to "api.example.com")
    println(app.host) // api.example.com
}

ตรวจสอบอย่างรวดเร็ว

คำสำคัญใดเลื่อนการเริ่มต้นของพร็อพเพอร์ตี val จนกว่าจะมีการเข้าถึงครั้งแรก

สรุปทบทวน

ใช้ ตัวแปรที่เริ่มต้นภายหลัง สำหรับพร็อพเพอร์ตีที่แก้ไขได้และไม่เป็นค่าว่าง ซึ่งเฟรมเวิร์กหรือการฉีดการพึ่งพาจะกำหนดค่าภายหลัง ใช้ ค่าที่อ่านได้อย่างเดียวแบบเริ่มต้นขี้เกียจ สำหรับค่าที่ควรคำนวณเพียงครั้งเดียวเมื่อเข้าถึงครั้งแรก ตรวจสอบสถานะด้วย ::prop.isInitialized

คำถามที่พบบ่อย

บทเรียน “lateinit และการเริ่มต้นแบบ Lazy” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “lateinit และการเริ่มต้นแบบ Lazy” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “lateinit และการเริ่มต้นแบบ Lazy”

ใช้ lateinit กับพร็อพเพอร์ตีที่กำหนดค่าภายหลัง และใช้ by lazy สำหรับการคำนวณแบบเลื่อนเวลา คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “lateinit และการเริ่มต้นแบบ Lazy” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม

ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. คอนสตรักเตอร์หลักและพารามิเตอร์พร็อพเพอร์ตี
  2. บล็อก init และลำดับการเริ่มต้น
  3. Getter และ Setter แบบกำหนดเองด้วย field
  4. lateinit และการเริ่มต้นแบบ Lazy
← กลับไปที่ Kotlin Academy