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);
}

A의 위의 코드 결과를 실행하는 런타임 Uncaught Error 하지만, 제거 const에서

var foo = const Foo([1,2,3,4]);

작동하도록합니다.


이것은 const 변수가 변경 될 수 있고 dart가 런타임에 이것을 감지하기 때문에 버그처럼 보입니다. 즉, const 객체가 수정 될 때 감지 할 수있는 수단이 있지만 컴파일 시간에 감지되어서는 안됩니다. const 변수는 " 컴파일 타임 상수 "라고합니다.

이것이 버그가 아니라면, 컴파일 타임에 const변수가 연산에 의해 변경 될 가능성이있는 시기를 감지 할 수있는 dart가 있습니까?

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객체의 속성 또는 실제로 객체가 생성되는 방식입니다. 그것은 개체에 몇 가지 결과를 가져올 수 있습니다. A const Foo(..)는 일반 Foo객체를 생성 하지만 완전히 불변하는 객체 만 생성 할 수 있으며 정규화됩니다. const [...]또는 const {...}댄 목록 /지도 / 세트 다른 종류의 생성 비 const가 문자 그대로,하지만 그 유형에 표시되지이다.

C ++에서 존재 const는 객체 참조의 속성이며 해당 참조를 사용할 수있는 방법을 제한하지만 그와 같은 상수 객체는 없습니다. 모든 개체를 const참조 로 전달할 수 있습니다 .

두 개념은 본질적으로 완전히 다르며 동일한 이름을 사용합니다 (또한 둘 다 JavaScript와 다릅니다 const).