Kotlin Academy · บทเรียน

Lambda พร้อมตัวรับ: รากฐานของ DSL

ทำความเข้าใจชนิดฟังก์ชันที่มีตัวรับและวิธีที่ชนิดเหล่านี้ทำให้ใช้ไวยากรณ์ DSL ได้

บทเรียน 1 จาก 413 ขั้นตอน

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

แลมบ์ดาที่มีตัวรับคืออะไร

แลมบ์ดาที่มีตัวรับคือลิเทอรัลฟังก์ชันที่ภายในบอดีสามารถเข้าถึงสมาชิกของออบเจ็กต์ตัวรับที่กำหนดไว้ได้โดยไม่ต้องใช้ตัวระบุใด ๆ ชนิดข้อมูลมีรูปแบบดังนี้: (ReceiverType) -> ReturnType ซึ่งเขียนเป็น ReceiverType.() -> ReturnType

เปรียบเทียบไวยากรณ์

แลมบ์ดาทั่วไป: { value: Int -> value + 1 } แลมบ์ดาที่มีตัวรับ: StringBuilder.() -> Unit — ภายในแลมบ์ดานี้ this หมายถึงอินสแตนซ์ของ StringBuilder

val addHello: StringBuilder.() -> Unit = {
    append("Hello")   // this = StringBuilder
    append(", World")
}

การใช้ with เพื่อใช้แลมบ์ดาที่มีตัวรับ

ฟังก์ชันในไลบรารีมาตรฐาน with รับตัวรับและแลมบ์ดาที่มีตัวรับ ฟังก์ชันนี้เรียกใช้แลมบ์ดาโดยให้ออบเจ็กต์ที่กำหนดเป็น this:

val result = with(StringBuilder()) {
    append("Kotlin")
    append(" DSLs")
    toString()
}  // result = "Kotlin DSLs"

การประกาศฟังก์ชันตัวสร้างของคุณเอง

คุณสามารถเขียนฟังก์ชันที่รับแลมบ์ดาที่มีตัวรับ เพื่อสร้าง API ตัวสร้างขนาดเล็กได้:

class HtmlTag(val name: String) {
    val children = mutableListOf<HtmlTag>()
    fun render(): String = "<$name>${children.joinToString("") { it.render() }}</$name>"
}

fun div(block: HtmlTag.() -> Unit): HtmlTag {
    val tag = HtmlTag("div")
    tag.block()
    return tag
}

การเรียกใช้ตัวสร้าง

ภายในแลมบ์ดา this คือ HtmlTag ดังนั้นจึงสามารถเข้าถึงสมาชิกของมันได้โดยตรง:

val page = div {
    children += HtmlTag("p")
}

apply คือแลมบ์ดาที่มีตัวรับ

ฟังก์ชันกำหนดขอบเขต apply เป็นตัวอย่างที่ง่ายที่สุด โดยเรียกใช้แลมบ์ดาที่มีตัวรับบน this แล้วคืนค่า this:

val list = mutableListOf<Int>().apply {
    add(1)
    add(2)
    add(3)
}   // list = [1, 2, 3]

รูปแบบ DSL

DSL สร้างขึ้นโดยการซ้อนฟังก์ชันตัวสร้างที่แต่ละฟังก์ชันรับแลมบ์ดาที่มีตัวรับ แต่ละระดับควบคุมตัวรับของตนเอง จึงได้โครงสร้างตามธรรมชาติที่มีการเยื้องและสะท้อนลำดับชั้นของข้อมูล

html {
    head { title("My Page") }
    body {
        div {
            p("Hello!")
        }
    }
}

ชนิดฟังก์ชันที่มีตัวรับ

คุณสามารถจัดเก็บแลมบ์ดาที่มีตัวรับไว้ในตัวแปรโดยใช้ชนิดฟังก์ชัน T.() -> R:

val greet: String.() -> String = { "Hello, $this!" }
println("World".greet())  // "Hello, World!"

ฟังก์ชันส่วนขยายกับแลมบ์ดาที่มีตัวรับ

ฟังก์ชันส่วนขยายและแลมบ์ดาที่มีตัวรับใช้กลไกเดียวกัน นั่นคือทั้งคู่มี this โดยนัย ความแตกต่างคือฟังก์ชันส่วนขยายถูกประกาศขณะคอมไพล์ ส่วนแลมบ์ดาที่มีตัวรับเป็นค่าที่สามารถส่งต่อไปใช้งานได้

การประกอบแลมบ์ดาที่มีตัวรับ

คุณสามารถประกอบฟังก์ชันตัวสร้างหลายฟังก์ชันเพื่อสร้าง DSL แบบลำดับชั้นที่มีความสามารถสูงได้ หัวใจสำคัญคือฟังก์ชันตัวสร้างแต่ละฟังก์ชันกำหนดตัวรับของตนเอง ทำให้ขอบเขตแยกจากกัน

การอนุมานชนิดข้อมูลและแลมบ์ดาที่มีตัวรับ

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

ตรวจสอบความเข้าใจ

ภายในแลมบ์ดาที่มีตัวรับชนิด StringBuilder.() -> Unit this หมายถึงอะไร?

สรุป: แลมบ์ดาที่มีตัวรับ

ประเด็นสำคัญ:

  • แลมบ์ดาที่มีตัวรับมี this โดยนัยภายในบอดีของแลมบ์ดา
  • ประกาศด้วยรูปแบบ ReceiverType.() -> ReturnType
  • เป็นรากฐานของ DSL ใน Kotlin ทั้งหมด
  • ไลบรารีมาตรฐานใช้รูปแบบนี้ใน apply, with, run, buildString และอื่น ๆ
เริ่มต้นได้ฟรี

เรียนรู้ Kotlin ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
51
บทเรียน
203

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

บทเรียน “Lambda พร้อมตัวรับ: รากฐานของ DSL” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “Lambda พร้อมตัวรับ: รากฐานของ DSL”

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

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

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

บทเรียน “Lambda พร้อมตัวรับ: รากฐานของ DSL” ใช้เวลานานแค่ไหน

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

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

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

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

  1. Lambda พร้อมตัวรับ: รากฐานของ DSL
  2. @DslMarker: ป้องกันการรั่วไหลของตัวรับ
  3. สร้าง DSL สำหรับ HTML/การกำหนดค่าที่ปลอดภัยด้านชนิด
  4. ทดสอบและพัฒนา DSL โดยไม่ทำลายผู้ใช้
← กลับไปที่ Kotlin Academy