Reputation: 1
I was attempting to test a simple piece of code involving multiplying the constant name by 20 however I noticed I had issues when I entered this code with constants:
void test() { const String name = "Foo"; const String nameTimes20 = name * 20; print(nameTimes20); }
In comparison to this code with final variables:
final String name = "Foo"; final String nameTimes20 = name * 20;`
I was curious as to why I need to use a final variable rather than a const as all the information needed for the operation is available at compile time.
Upvotes: 0
Views: 36
Reputation: 71613
String.operator*
is not an allowed constant expression.
Dart has a list of operations, and types of their operands, that are allowed to be constant, and string * int
is not on that list.
It could be allowed, there is no technical issue with doing so, the compiler can easily figure out what the result should be without running any user code.
One reason for not allowing the operation is that it allows allocating arbitrarilty large strings at compile-time. Dart constants are otherwise limited to allocations that are linear in the source code size. It cannot allocate a list with more elements than those written in the source code. It cannot allocate more constant objects than there are constant collection or constructor invocations in the program.
(It's not entirely correct, still because of strings, because String.operator+
and "$s1$2"
are valid constant operations, and you can do const v1 = "ab", v2 = v1+v1, v3 = v2+v2, .... , v10=v9+v9;
and create a string that's exponential in the source code size. So don't do that. It's still more work than var v20 = "ab" * 1048576;
, so it likely won't happen by accident.)
Another thing is that it would likely be a potentially constant expression too, usable in constant constructors, so you can write:
class Foo {
final String v;
const Foo(String s, int n) : v = s * n;
}
which can lead to doing large allocations without being able to see the operation where the big number is written.
Strings are objects, even if we often treat them as primitive values, and they are the only objects with non-trivial size that can be allocated by a constant or potentially constant expression.
So, it's not allowed, and it's for your own protection (against other people creating multi-megabyte constant strings that slow down your compilation).
Upvotes: 1