14

So in other languages there are ArrayList or MutableList which allows modifications (add, delete, remove) to list items. Now to avoid modification of these list, simply return the MutableList or ArrayList as a List.

I want to do the same thing in Dart. But in Dart returning a List still allows you to do list.add. How can this be done properly in Dart?

Archie G. Quiñones
  • 11,638
  • 18
  • 65
  • 107

5 Answers5

19

You may use Iterable<type>. It is not a List<type>, it does not provide methods to modify, but it does to iterate. It also provides a .toList() method, if needed. Depending on your construction, it may be better to use Iterable instead of List to ensure consistency.

Almost good

final Iterable<int> foo = [1, 2, 3];
foo.add(4); // ERROR: The method 'add' isn't defined.

// WARNING: following code can be used to mutate the container.
(foo as List<int>).add(4);
print(foo); // [1, 2, 3, 4]

Even though foo is instantiated as a mutable List, the interface only says it is an Iterable.

Good

Using List<E>.unmodifiable constructor:

final Iterable<int> foo = List.unmodifiable([1, 2, 3]);
foo.add(4); // ERROR: The method 'add' isn't defined.

(foo as List<int>).add(4); // Uncaught Error: Unsupported operation: add

// The following code may appear to be circumventing 
// the implemented restriction, but it is 
// OK because it does not mutate foo; rather, 
// foo.toList() returns a separate instance.
foo.toList().add(4);
print(foo); // [1, 2, 3]
Ardent Coder
  • 3,777
  • 9
  • 27
  • 53
rserro
  • 191
  • 1
  • 3
13

As Irn said, there is no type for immutable lists in Dart, but this supplemental answer shows examples of creating immutable lists. You can't add, remove, or modify the list elements.

Compile time constant list variables

Use the const keyword to create the list.

const myList = [1, 2, 3];

Note: Adding the optional const keyword before the list literal is redundant when the variable is already const.

const myList = const [1, 2, 3];

Compile time constant list values

If the variable can't be a const, you can still make the value be const.

final myList = const [1, 2, 3];

Runtime constant list

If you don't know what the list elements are until runtime, then you can use the List.unmodifiable() constructor to create an immutable list.

final myList = List.unmodifiable([someElement, anotherElement]);
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
9

There is no type for unmodifiable lists in Dart, just the List type. Some List implementations accept calling add, others do not.

You can return an actually unmodifiable list, say created using List.unmodifiable, as a List. The user will get a run-time error if they try to call add on it.

lrn
  • 64,680
  • 7
  • 105
  • 121
4

To prevent modifications on your list, just use a UnmodifiableListView from the built-in dart:collection library:

import 'package:collection/collection.dart';

List<int> protectedNumbersUntil4() {
  return UnmodifiableListView([0, 1, 2, 3, 4]);
}

final numbers = protectedNumbersUntil4();
numbers.add(5); // throws
palsch
  • 5,528
  • 4
  • 21
  • 32
3

You should use IList an immutable list from package:darts/dartz.dart the next best solution would be to use KtList (which is an immutable Kotlin collection), both are immutable and will serve as immutable lists, however, I prefer KtList as it is much easier to use.

Also, check out this medium post on immutability ( https://medium.com/dartlang/an-intro-to-immutability-with-dart-d4de871865c7 )

And this one on ktlist https://medium.com/flutter-community/kt-dart-better-collections-for-your-flutter-business-logic-41886ab7883

Ferdinand
  • 513
  • 1
  • 3
  • 9