Flutter: const vs final ใช้ยังไงดี!

Published on

Authored by Pete. Pittawat Taveekitworachai.


หลาย ๆ คนถ้าได้เขียน Flutter มาสักพัก จะพบกับความแปลกประหลาดอย่างหนึ่งที่ไม่เหมือนภาษาอื่น นั่นก็คือ Dart ซึ่งเป็น programming language ของ Flutter มีทั้ง const และ final แล้วแบบนี้เราควรจะใช้ตัวไหนเมื่อไรดีละ!


const

const เป็น keyword สำหรับใช้ประกาศตัวแปรที่เป็นค่าคงที่ ซึ่งเรารู้ค่าก่อน compile นั่นหมายความว่าเราควรใช้ const เมื่อเรารู้ค่าที่แน่นอนของตัวแปรนั้น ๆ หรือในอีกนัยหนึ่งก็คือค่าคงที่ทั่วไปนั่นเอง นอกจากนี้เมื่อเราประกาศตัวแปรใด ๆ เป็น const เราจะถือว่าตัวแปรนั้น ๆ เป็น final ด้วยเช่นกัน (ไม่สามารถ reassign ได้)

ตัวอย่างการใช้ const เช่น

    const pi = 3.14

ถ้าสังเกตดี ๆ อีกอย่างหนึ่งเราจะพบว่า pi ในทีนี้ถูกตั้งชื่อ (naming) ด้วยตัวพิมพ์เล็กทั้งหมด ซึ่งค่อนข้างขัดกับความรู้สึกของหลาย ๆ คน โดยเฉพาะคนที่เขียน Java มาก่อน ซึ่งเรามักจะตั้งชื่อตัวแปรเป็นตัวพิมพ์ใหญ่ทั้งหมด ส่วนเหตุผลที่ Dart แนะนำให้เราใช้ lowerCamelCase นั้นก็เป็นเพราะว่า

  • การตั้งชื่อเป็นตัวพิมพ์ใหญ่ล้วนนั้น ดูแย่ในหลายกรณี โดยเฉพาะการใช้ enum
  • หลายครั้งที่ตัวแปรที่เป็นค่าคงที่ของเรามักถูกแก้ไขให้กลายเป็นตัวแปรที่ไม่ใช่ค่าคงที่อีกต่อไป นั่นทำให้นอกจากเราต้องแก้ keyword const แล้ว เรายังต้องเสียเวลาแก้ชื่อตัวแปรอีกด้วย

final

สำหรับ final นั้นเป็น keyword ที่ใช้สำหรับประกาศตัวแปรที่เป็นค่าคงที่ ณ เวลารัน (runtime constant) ซึ่งจะอนุญาตให้เรา assign ค่าให้ตัวแปรนี้ได้เพียงครั้งเดียวเท่านั้น และไม่สามารถแก้ไขค่าได้อีก อย่างไรก็ตามมีข้อควรระวังคือ collection type ต่าง ๆ นั้นยังคงเป็น reference type ทำให้แน่ใจว่าเราจะไม่สามารถ reassign ได้ แต่เรายังคงแก้ไขของที่อยู่ใน collection นั้น ๆ ได้อยู่ ถ้าอยากให้ของที่อยู่ในนั้น Immutable เราอาจจะต้องใช้ Class อื่น ๆ เข้ามาช่วย เช่น UnmodifiableListView นั่นเอง (แตกต่างกับ const ซึ่งจะ implicit ด้วยว่าของที่ collection นั้น ๆ จะถูกประกาศเป็น const เช่นกัน) นอกจากนี้ final ยังเป็น keyword ที่มักจะถูกใช้กับ instance variable ของคลาสอีกด้วย (แน่นอนว่ายกเว้นกรณีที่ตัวแปรนั้น ๆ เป็น static variable ซึ่งเราจะใช้ keyword const แทน ถ้าเป็นค่าคงที่)

ข้อควรระวังหนึ่งของการใช้ final คือ เราต้องทำการ initialize ค่าเสมอ ไม่เช่นนั้น Dart Analyzer อาจจะไม่พอใจได้


Tip!

นอกจากนี้ใน Flutter ถ้า widget ไหนที่มี const constructor เรายังสามารถใส่ keyword const นำหน้า constructor ของ widget นั้น ๆ เวลาใช้ได้อีกด้วย เช่น

    // ...
    Container(
      child: const Text('static text'),
    ),
    // ...

โดยข้อดีของการใช้ const นำหน้า widget constructor แบบนี้ ก็คือการที่เราบอก Flutter ว่าตอนที่มีการเปลี่ยนแปลง state เกิดขึ้น และ Flutter ต้องการท่องไปใน Tree เมื่อเจอ const ที่ widget ใดก็ตาม Flutter จะถือว่า widget นั้น ๆ (รวมถึง subtree ของ widget นั้นด้วย) ไม่มีการเปลี่ยนแปลงแน่นอน (โดยทั่วไปมักเป็น EdgeInset, Color, Icon, Text) และหยุดการท่องไปใน subtree นั้นทันที ทำให้ประหยัดทรัพยากรในการท่องและเช็คการเปลี่ยนแปลงเพื่อใช้ในการวาด UI ใหม่ เมื่อ state มีการเปลี่ยนแปลง


Summary

ใช้ const เมื่อต้องการสร้างค่าคงที่ที่เรารู้ค่าแน่นอน และใช้ final เมื่อต้องการสร้างค่าคงที่ที่เราจะรู้ค่าเมื่อ run


📚 Hope you enjoy reading! 📚