ตรวจจับเมื่อวัตถุ const ถูกส่งผ่านไปยังฟังก์ชันที่กลายพันธุ์ใน Dart
ใช้ตัวอย่างนี้:
void modl(List<int> l) {
l.add(90);
print(l);
}
class Foo {
final List<int> bar;
const Foo(this.bar);
@override
String toString() => 'Foo{bar: $bar}';
}
void main() {
var foo = const Foo([1,2,3,4]);
modl(foo.bar);
print (foo);
}
การรันโค้ดด้านบนส่งผลให้รันไทม์ Uncaught Error
แต่การลบconst
จาก
var foo = const Foo([1,2,3,4]);
อนุญาตให้ใช้งานได้
สิ่งนี้ดูเหมือนจะเป็นข้อบกพร่องสำหรับฉันเพราะตัวแปร const สามารถกลายพันธุ์ได้และ dart ตรวจพบสิ่งนี้ที่รันไทม์ซึ่งหมายความว่ามีวิธีตรวจจับเมื่อวัตถุ const ถูกแก้ไข แต่ไม่ควรตรวจพบในเวลาคอมไพล์โดยเห็นว่า ตัวแปร const เรียกว่า " ค่าคงที่เวลาคอมไพล์ "
หากนี่ไม่ใช่จุดบกพร่องมีอะไรในโผที่ช่วยให้เราตรวจจับได้ในเวลาคอมไพล์เมื่อconst
ตัวแปรอาจกลายพันธุ์โดยการดำเนินการ?
ใน C ++ คอมไพเลอร์เกิดข้อผิดพลาดเมื่อเราพยายามทำสิ่งนี้ มีอะไรที่เราสามารถทำได้ใน Dart เพื่อหลีกเลี่ยงการพบข้อผิดพลาดนี้ในรันไทม์?
คำตอบ
ไม่ Dart const
เป็นคุณลักษณะเวลาคอมไพล์รอบ ๆ การสร้างออบเจ็กต์ แต่จะไม่แสดงในระบบประเภท คุณไม่สามารถบอกได้จากประเภทของวัตถุใด ๆ ว่าเป็นค่าคงที่หรือไม่
โดยปกตินั่นไม่ใช่ปัญหาเนื่องจากอินสแตนซ์ของคลาสที่สามารถเป็น const นั้นไม่สามารถแก้ไขได้ ไม่รับประกันว่าจะไม่เปลี่ยนรูปอย่างละเอียด แต่อินสแตนซ์เองไม่สามารถเปลี่ยนฟิลด์ได้
รายการชุดและแผนที่อาจเป็นค่าคงที่และเปลี่ยนแปลงได้ นั่นคือสิ่งที่คุณเห็นที่นี่ อาร์กิวเมนต์รายการconst Foo(const [1, 2, 3, 4])
เป็นค่าคงที่แม้ว่าคุณจะลบซ้ำซ้อนconst
ในลิสต์ลิเทอรัล คุณจะมีปัญหาเดียวกันกับnew Foo(const [1, 2, 3, 4])
ที่ยังจะให้เปลี่ยนรูปแต่ที่อื่นจะแยกไม่ออกจากfoo.bar
new Foo([1, 2, 3, 4])
ข้อแตกต่างที่แท้จริงเพียงอย่างเดียวคือรายการนั้นสามารถแก้ไขได้หรือไม่และวิธีเดียวที่จะตรวจพบคือพยายามแก้ไข
รายการชุดและแผนที่ไม่ได้ให้วิธีใด ๆ ในการตรวจสอบว่ามีการเปลี่ยนแปลงหรือไม่ยกเว้นการพยายามและการตรวจจับข้อผิดพลาด
เมื่อเปรียบเทียบกับ C ++ ความคิดของ Dart เกี่ยวกับการconst
เป็นเป็นคุณสมบัติของวัตถุหรือจริงๆแล้ววิธีการสร้างวัตถุ นั่นอาจมีผลบางอย่างกับวัตถุ const Foo(..)
เพียงสร้างปกติFoo
วัตถุ แต่ก็สามารถสร้างวัตถุไม่เปลี่ยนรูปได้อย่างล้ำลึกและพวกเขาจะ canonicalized A const [...]
หรือconst {...}
สร้างรายการ / แผนที่ / ชุดประเภทที่แตกต่างจากลิเทอรัลที่ไม่ใช่ const แต่ไม่ปรากฏในประเภท
ใน C ++ const
เป็นคุณสมบัติของการอ้างอิงอ็อบเจ็กต์และ จำกัด วิธีใช้การอ้างอิงนั้น แต่ไม่มีอ็อบเจ็กต์คงที่เช่นนี้ สามารถส่งผ่านวัตถุใด ๆ เป็นconst
ข้อมูลอ้างอิงได้
ทั้งสองแนวคิดมีลักษณะแตกต่างกันอย่างสิ้นเชิงและเพิ่งใช้ชื่อเดียวกัน (และต่างจาก JavaScript ด้วยconst
)