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

ตัวปรับแต่ง noinline และ crossinline

ควบคุมพฤติกรรมการ inline สำหรับพารามิเตอร์ lambda เฉพาะในฟังก์ชัน inline

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

ปัญหาที่ inline แก้ไขและก่อให้เกิด

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

noinline: การคงแลมบ์ดาหนึ่งตัวไว้เป็นออบเจ็กต์

เติม noinline หน้าพารามิเตอร์แลมบ์ดาที่ต้องการ เพื่อยกเว้นแลมบ์ดานั้นจากการแทรกโค้ด ขณะที่แลมบ์ดาที่เหลือยังคงถูกแทรกโค้ด

inline fun doWork(
    action: () -> Unit,
    noinline callback: () -> Unit   // stored, not inlined
) {
    action()                        // inlined at call site
    scheduleCallback(callback)      // passed as object — valid
}

เมื่อใดจำเป็นต้องใช้ noinline

คุณต้องใช้ noinline เมื่อแลมบ์ดาถูก:

  • เก็บไว้ในตัวแปรหรือฟิลด์
  • ส่งให้ฟังก์ชันอื่นที่ต้องการชนิดฟังก์ชัน
  • ส่งคืนจากฟังก์ชัน inline

crossinline: การห้ามคืนค่าข้ามขอบเขต

ใช้ crossinline เมื่อแลมบ์ดาที่ถูกแทรกโค้ดจะถูกเรียกใช้ในบริบทการทำงานอื่น (เช่น ภายในแลมบ์ดาอื่นหรือในเธรดอื่น) โดยบอกคอมไพเลอร์ว่าให้แทรกแลมบ์ดานี้ แต่ห้ามการคืนค่าข้ามขอบเขตภายในแลมบ์ดา

inline fun runAsync(crossinline block: () -> Unit) {
    Thread {
        block()   // block is inlined but cannot use non-local return
    }.start()
}

เหตุใดการคืนค่าข้ามขอบเขตจึงอันตรายในกรณีนี้

หาก block ใช้ return แบบข้ามขอบเขตได้ ก็จะพยายามคืนค่าจากฟังก์ชันที่เรียก runAsync แต่เมื่อเธรดเริ่มทำงาน ฟังก์ชันนั้นอาจคืนค่าไปแล้ว ซึ่งทำให้เกิดพฤติกรรมที่ไม่ได้กำหนดไว้ crossinline ป้องกันปัญหานี้ตั้งแต่เวลาคอมไพล์

การใช้ noinline และ crossinline ร่วมกัน

ฟังก์ชัน inline หนึ่งฟังก์ชันสามารถผสมพารามิเตอร์แบบปกติ, noinline และ crossinline ได้:

inline fun orchestrate(
    crossinline setup: () -> Unit,
    action: () -> Unit,
    noinline teardown: () -> Unit
) {
    Thread { setup() }.start()
    action()
    register(teardown)
}

ข้อผิดพลาดของคอมไพเลอร์เมื่อไม่มี crossinline

หากส่งแลมบ์ดาที่ถูกแทรกโค้ดไปยังบริบทแลมบ์ดาโดยไม่มี crossinline คอมไพเลอร์จะแสดงข้อความ: "ไม่สามารถแทรก 'block' ที่นี่ได้: อาจมีการคืนค่าข้ามขอบเขตอยู่ ให้เพิ่มตัวปรับแต่ง crossinline"

การใช้งานในไลบรารีมาตรฐาน

ไลบรารีมาตรฐานใช้ crossinline ในฟังก์ชันอย่าง Sequence { } และตัวสร้างโครูทีนบางตัว เพื่อให้มั่นใจว่าแลมบ์ดาที่ผู้ใช้ส่งเข้ามาจะทำงานอย่างปลอดภัยในบริบทอื่น

noinline ไม่ได้ปิดการทำงานของ inline

การกำหนดพารามิเตอร์หนึ่งตัวเป็น noinline ไม่ได้ปิดการแทรกโค้ดของทั้งฟังก์ชัน ตัวฟังก์ชันและพารามิเตอร์แลมบ์ดาอื่น ๆ ยังคงถูกแทรกโค้ด มีเพียงแลมบ์ดาที่กำกับด้วย noinline เท่านั้นที่ยังคงรักษาเอกลักษณ์ของออบเจ็กต์ไว้

ข้อควรพิจารณาด้านประสิทธิภาพ

noinline ทำให้พารามิเตอร์นั้นมีต้นทุนการจัดสรรแลมบ์ดาตามปกติ ส่วน crossinline ยังคงแทรกโค้ด โดยมีข้อจำกัดเพียงห้ามการคืนค่าข้ามขอบเขต ตัวปรับแต่งทั้งสองไม่มีผลต่อการแทรกโค้ดของพารามิเตอร์อื่น

ตารางสรุป

สรุปตัวปรับแต่ง:

  • ไม่มีตัวปรับแต่ง → แลมบ์ดาถูกแทรกโค้ดทั้งหมด และอนุญาตให้คืนค่าข้ามขอบเขต
  • noinline → เก็บแลมบ์ดาไว้เป็นออบเจ็กต์ และสามารถจัดเก็บหรือส่งต่อได้
  • crossinline → แทรกโค้ดแลมบ์ดา แต่ห้ามการคืนค่าข้ามขอบเขต

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

เมื่อใดที่ต้องใช้ noinline กับพารามิเตอร์แลมบ์ดาของฟังก์ชัน inline

ทบทวน: noinline และ crossinline

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

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

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

บทเรียน “ตัวปรับแต่ง noinline และ crossinline” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “ตัวปรับแต่ง noinline และ crossinline”

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

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

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

บทเรียน “ตัวปรับแต่ง noinline และ crossinline” ใช้เวลานานแค่ไหน

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

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

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

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

  1. ฟังก์ชัน inline: ลดต้นทุนของ Lambda
  2. ตัวปรับแต่ง noinline และ crossinline
  3. พารามิเตอร์ชนิด reified: เข้าถึง T ขณะรันไทม์
  4. รูปแบบ reified เชิงปฏิบัติ: การแยกวิเคราะห์ DI และการทำซีเรียลไลซ์
← กลับไปที่ Kotlin Academy