40

为什么List()Dart 的 null 安全后无法访问构造函数?

// Compile time error: 'List' is deprecated and shouldn't be used.
// The default 'List' constructor isn't available when null safety is enabled. 
// Try using a list literal, 'List.filled' or 'List.generate'.
List<int> foo = List(); 

但是,您仍然可以这样做:

List<int> foo = []; // No error

那么,两者有什么区别呢?他们要么都应该显示错误,要么都不显示。

4

4 回答 4

87

简短的回答:

而不是 pre-null-safety 操作

var foo = List<int>();  // Now error
var bar = List<int>(n); // Now error
var baz = List<int>(0); // Now error

使用以下内容:

var foo = <int>[];           // Always the recommended way.
var bar = List.filled(1, 0); // Not filled with `null`s.
var baz = List<int>.empty();

长答案:

构造List函数有两个用途:

  • new List()创建一个空的可增长列表,相当于[].
  • new List(n)创建一个用值n填充的固定长度列表null

在零安全的情况下,第二次使用大部分时间都是不可靠的,并且没有好的方法来修复它。可以强制类型参数不可为空,但List<T>(4)仅在T时有效。没有办法强制执行。

因此,List(n)需要采用的模式(取而代之的List.filled(n, value)是强制您提供填充值)。剩下List()的,它并没有真正承载自己的重量。您可以[]改为使用(而且您应该!),因此决定完全删除构造函数 - 它的所有用途都是不安全或无用的。(此外,它已经是一个奇怪的构造函数,因为如果我们想正确地使其为 null 安全,它将具有一个不可为 null 的类型且没有默认值的可选参数。)

通过完全删除它,它可以潜在地List在未来引入一个新的构造函数,也许作为List.filled. 一个人可以希望。

于 2020-08-17T20:30:31.123 回答
3

这是因为默认的List()元素已被弃用,您如何尝试使用 List.filled() 元素,如下所示

void display() {
    var fixedList = new List<int>.filled(5, 0, growable: false);
    fixedList[0] = 0;
    fixedList[1] = 10;
    fixedList[2] = 20;
    fixedList[3] = 30;
    fixedList[4] = 40;
    print('Elements in the list are as follows: $fixedList');
  }
} 

而对于可增长长度列表,您可以尝试如下所示:

void main() {
    var growableList = new List<int>.filled(0,0, growable:true);
    growableList = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90];
    print('The elements in the growable list include: $growableList');
  }
于 2021-05-11T13:19:59.603 回答
3

除了@lrn sir 提到的内容之外,您还可以使用以下方法创建一个列表:

List<int> foo = List<int>.empty(growable: true); // []
于 2021-09-06T00:24:34.107 回答
0

_items = List<DropdownMenuItem<String>>();可以写成空安全为

_items = List<DropdownMenuItem<String>>.from(<DropdownMenuItem<String>>[]);
于 2022-03-01T04:16:48.893 回答