jesper
jesper

Reputation: 395

const constructor initialisation failure in Dart

The following:

import 'package:flutter/foundation.dart';

class Bar {
  final int tender;
  
  const Bar(this.tender);
}

class Foo {
  final int foo;
  final Bar bar;

  const Foo({@required foo})
    : foo = foo,
      bar = const Bar(foo);
}

results in the compiler error "Arguments of a constant creation must be constant expressions" for the attempted initialization bar = const Bar(foo). Why does that line fail, when the preceding line foo = foo does not?

EDIT Just to further clarify the source of confusion: effectively, it's as if it's ok to const-construct a Foo with the argument foo (which is unknown at compile-time), but it's not ok to const-construct a Bar with the exact same argument. Why?

Upvotes: 2

Views: 185

Answers (1)

dev-aentgs
dev-aentgs

Reputation: 1288

The line fails because a variable is being passed instead of a constant/literal to create the const object of Bar. The compiler doesn't know what foo is going to be at compile time and hence it fails to create a const Bar(foo)

Consider this :

void main(){
  int someNonConstantValue = 10;
  const Bar(someNonConstantValue);
}

Compiler warns here with the same error message

Arguments of a constant creation must be constant expressions

This is because someNonConstantValue is not a constant.

Now if the code is modified as :

void main(){
  const int someConstantValue = 10;
  const Bar(someConstantValue);
}

There are no warnings because compiler is now assured that someConstantValue is actually constant and wont change anytime (and hence it can compile and optimize the code).

Similarly, In the original example, compiler doesn't give error if changes are made as such to use a constant literal for creating const Bar(

class Bar {
  final int tender;
  const Bar(this.tender);
}

class Foo {
  final int foo;
  final Bar bar;

  const Foo({@required this.foo})
    : bar = const Bar(10);
} 

Addition : Following the same explanation as above, error is given if const Foo( is passed a variable

void main(){
  int someNonConstantValue = 10;
  const Foo(foo:someNonConstantValue);
}

The point you are referring to is the constructor declaration inside its own class. It hasn't been invoked with any value yet.

EDIT:

This github issue is a discussion on similar lines from early days of Dart.

This answer provides explanation about the same.

Upvotes: 3

Related Questions