I am trying out the example given in the Freezed page at https://pub.dev/packages/freezed. This is the example I am testing replacing int with List<int> adding a [40] as default.
@Freezed(makeCollectionsUnmodifiable: false)
class Example with _$Example {
factory Example([@Default([40]) List<int> list]) = _Example;
factory Example.fromJson(Map<String, dynamic> json) => _$ExampleFromJson(json);
}
using the Example class:
final e = Example(); //default parameter [40]
//e.list.add(42); //error producing line
print('e $e');
final f = Example([40]); //parameter same as default value
f.list.add(42);
print('f $f');
final g = Example([41]); //another parameter
g.list.add(42);
print('g $g');
The output is:
e Example(list: [40])
f Example(list: [40, 42])
g Example(list: [41, 42])
If I remove the comment in the default parameter case, I get the following error:
Unhandled exception:
Unsupported operation: Cannot add to an unmodifiable list
#0 UnmodifiableListMixin.add (dart:_internal/list.dart:114:5)
#1 main (file:///D:/Dart/darttest/bin/darttest.dart:27:10)
#2 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
Why the list becomes unmodifiable?
CodePudding user response:
Dart annotations are used by code generators that parse the source code. As the expressions inside annotations do not get executed, they must be constant expressions that can be computed during compilation.
Objects constructed with the const
keyword must be immutable. They cannot change, as is written in the Dart Language Tour:
You can’t change the value of a const variable:
baz = [42]; // Error: Constant variables can't be assigned a value.
Although a final object cannot be modified, its fields can be changed. In comparison, a const object and its fields cannot be changed: they’re immutable.
var constantList = const [1, 2, 3]; // constantList[1] = 1; // This line will cause an error.
To provide a default list value in the annotation, it must be const
and therefore unmodifiable.
A note on Freezed
On another note, modifying lists goes against the entire Freezed concept. Freezed is used to generate immutable data structures, that can be updated with the copyWith
method. It's a mistake to modify any collections in Freezed classes.
A recent update does add mutability through the unfreezed
annotation, which should be used for mutable classes.