无法无条件调用方法“[]”,因为接收者可以为“null”

Posted

技术标签:

【中文标题】无法无条件调用方法“[]”,因为接收者可以为“null”【英文标题】:The method '[]' can't be unconditionally invoked because the receiver can be 'null' 【发布时间】:2021-08-07 01:57:42 【问题描述】:

我是 Flutter 的新手。我正在尝试开发一个应用程序。

我想在 Firebase 数据库中显示员工列表。但是,我收到以下错误。

错误:

方法'[]'不能被无条件调用,因为接收者 可以为“空”。尝试使调用有条件(使用'?.')或添加 对目标 ('!') 的空检查。

科德拉姆:

`import 'package:calendar/page/mainPage.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class Staff extends StatefulWidget 
  @override
  _StaffState createState() => _StaffState();


class _StaffState extends State<Staff> 
  
  final _firestore = FirebaseFirestore.instance;

  @override
  Widget build(BuildContext context) 
    // ignore: unused_local_variable
    CollectionReference staffRef = _firestore.collection('staff');

    return Scaffold(
      appBar: AppBar(
        title: Text("Personel Listesi"),
        backgroundColor: Colors.redAccent[400],
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.home),
            onPressed: () 
              Navigator.pushAndRemoveUntil(
                  context,
                  MaterialPageRoute(builder: (_) => MainPage()),
                  (route) => true);
            ,
          ),
        ],
      ),
      body: Container(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Center(
            child: Column(
              children: [
                StreamBuilder<QuerySnapshot>(
                  stream: staffRef.snapshots(),
                  builder: (BuildContext context, AsyncSnapshot asyncSnapshot) 
                    if (asyncSnapshot.hasError) 
                      return Center(
                          child: Text(
                              "Bir hata oluştu, lütfen tekrar deneyiniz."));
                     else 
                      if (asyncSnapshot.hasData) 
                        List<DocumentSnapshot> listStaff =
                            asyncSnapshot.data.docs;
                        return Flexible(
                          child: ListView.builder(
                              itemBuilder: (context, index) 
                                return Card(
                                  elevation: 20,
                                  color: Colors.greenAccent[200],
                                  child: ListTile(
                                    trailing: IconButton(
                                      icon: Icon(Icons.delete),
                                      onPressed: () async 
                                        await listStaff[index]
                                            .reference
                                            .delete();
                                      ,
                                    ),
                                    title: Text(
                                      '$listStaff[index].data['nameSurname']',
                                      style: TextStyle(fontSize: 20),
                                    ),
                                    subtitle: Column(
                                      children: [
                                        Row(
                                          mainAxisAlignment:
                                              MainAxisAlignment.start,
                                          children: [
                                            Text(
                                              '$listStaff[index].data['tip']',
                                              style: TextStyle(fontSize: 14),
                                            ),
                                          ],
                                        ),
                                        Row(
                                          mainAxisAlignment:
                                              MainAxisAlignment.start,
                                          children: [
                                            Text(
                                              '$listStaff[index].data['mail']',
                                              style: TextStyle(fontSize: 14),
                                            ),
                                          ],
                                        ),
                                        Row(
                                          mainAxisAlignment:
                                              MainAxisAlignment.start,
                                          children: [
                                            Text(
                                              '$listStaff[index].data['phone']',
                                              style: TextStyle(fontSize: 14),
                                            ),
                                          ],
                                        ),
                                      ],
                                    ),
                                  ),
                                );
                              ,
                              itemCount: listStaff.length),
                        );
                       else 
                        return Center(
                          child: CircularProgressIndicator(),
                        );
                      
                    
                  ,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  

`

【问题讨论】:

【参考方案1】:

在新的flutter更新中,我们不需要添加.data()

下面是我的代码

title: Text(
                                  **'$listStaff[index].data['nameSurname']',**
                                  style: TextStyle(fontSize: 20),
                                ),

像这样更改它修复了错误。

title: Text(
                                  **'$listPersonel[index]['nameSurname']'**,
                                  style: TextStyle(fontSize: 20),
                                ),

【讨论】:

【参考方案2】:

问题:

如果您正在访问可空的 ListMap 上的元素,则会收到此错误。让我们为List 理解它,您可以为您的Map 应用相同的解决方案。

例如:

List<int>? someList;

void main() 
  int a = someList[0]; // Error


解决方案:

使用局部变量

var list = someList;
if (list != null) 
  int a = list[0]; // No error

使用 ???

int a = someList?[0] ?? -1; // -1 is the default value if List was null

仅当您确定 List 不是 null 时才使用 ! bang 运算符。

int a = someList![0];

对于那些正在使用FutureBuilder/StreamBuilder的人:

您可以通过两种方式解决该错误:

为您的FutureBuilder/StreamBuilder指定一个类型

FutureBuilder<List<int>>( // <-- type 'List<int>' is specified.
  future: _listOfInt(),
  builder: (_, snapshot) 
    if (snapshot.hasData) 
      List<int> myList = snapshot.data!; // <-- Your data
    
    return Container();
  ,
)

使用asObject 向下转换为您的类型,例如ListMap

FutureBuilder(
  future: _listOfInt(),
  builder: (_, snapshot) 
    if (snapshot.hasData) 
      var myList = snapshot.data! as List<int>; // <-- Your data using 'as'
    
    return Container();
  ,
)

【讨论】:

【参考方案3】:

这是一个典型的空安全相关错误。我没有尝试代码,我猜可能将asyncSnapshot.data.docs 分配给listStaff 可能会返回null,但您声明的类型List&lt;DocumentSnapshot&gt; 不允许这样做。如果你 100% 确定这个赋值不会返回空值,你可以添加 '!'确保编译器,它将是列表,所以它会让你使用方法。虽然如果您希望此列表为空,您可以简单地添加“?”显示它,而不是使用 '?.'使用方法。它的工作原理是:检查对象是否为空,如果不是,则在此方法上执行方法。

【讨论】:

以上是关于无法无条件调用方法“[]”,因为接收者可以为“null”的主要内容,如果未能解决你的问题,请参考以下文章

不能无条件调用运算符“*”,因为接收者可以为“null”。尝试向目标添加空检查('!')

无法无条件访问属性“uid”,因为接收者可以为“null”

不能无条件访问属性“长度”,因为接收者可以为“空”。尝试使访问有条件(使用'?.')或添加

如果 APi 响应为空,如何设置条件然后执行以下 VUEjs?

Flutter - '属性'设置'不能无条件访问,因为接收器可以是'null''

接收集合并为每个元素调用其链接块的 TPL 数据流