如何在 Dart 中返回一个不可变的列表?

Arc*_*nes 3 dart

因此,在其他语言中,有ArrayListMutableList允许修改(添加、删除、删除)以列出项目。现在为了避免修改这些列表,只需将MutableListorArrayList作为List.

我想在Dart. 但在Dart返回一个List仍然允许你做list.add。这如何在 Dart 中正确完成?

小智 25

您可以使用Iterable<type>. 它不是 a List<type>,它不提供修改方法,但它提供迭代方法。如果需要的话,它还提供了一种.toList()方法。根据您的构造,使用Iterable而不是List确保一致性可能会更好。

几乎不错

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]
Run Code Online (Sandbox Code Playgroud)

即使foo被实例化为可变的List,接口也只说它是一个Iterable

好的

使用List<E>.unmodifiable构造函数:

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]
Run Code Online (Sandbox Code Playgroud)


lrn*_*lrn 8

没有类型为飞镖不可修改的列表,只是List类型。有些List实现接受调用add,有些则不接受。

您可以返回一个实际不可修改的列表,比如使用List.unmodifiable,创建的List. 如果用户尝试调用add它,则会收到运行时错误。


Sur*_*gch 5

正如 Irn 所说,Dart 中没有不可变列表的类型,但此补充答案显示了创建不可变列表的示例。您不能添加、删除或修改列表元素。

编译时常量列表变量

使用const关键字创建列表。

const myList = [1, 2, 3];
Run Code Online (Sandbox Code Playgroud)

注意const当变量已经存在时,在列表文字之前添加 optional关键字是多余的const

const myList = const [1, 2, 3];
Run Code Online (Sandbox Code Playgroud)

编译时常量列表值

如果变量不能是 a const,您仍然可以将值设为const

final myList = const [1, 2, 3];
Run Code Online (Sandbox Code Playgroud)

运行时常量列表

如果您直到运行时才知道列表元素是什么,那么您可以使用List.unmodifiable()构造函数来创建一个不可变的列表。

final myList = List.unmodifiable([someElement, anotherElement]);
Run Code Online (Sandbox Code Playgroud)


pal*_*sch 5

要防止列表被修改,只需使用UnmodifiableListView内置dart:collection库中的 a:

import 'package:collection/collection.dart';

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

final numbers = protectedNumbersUntil4();
numbers.add(5); // throws
Run Code Online (Sandbox Code Playgroud)