ตรวจจับเมื่อวัตถุ const ถูกส่งผ่านไปยังฟังก์ชันที่กลายพันธุ์ใน Dart

Aug 17 2020

ใช้ตัวอย่างนี้:

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 เพื่อหลีกเลี่ยงการพบข้อผิดพลาดนี้ในรันไทม์?

คำตอบ

3 lrn Aug 17 2020 at 04:53

ไม่ 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)