【问题标题】:dart The method 'validate' can't be unconditionally invoked because the receiver can be 'null'dart 方法 'validate' 不能被无条件调用,因为接收者可以是 'null'
【发布时间】:2023-04-10 16:45:01
【问题描述】:

我正在研究 Flutter,但我遇到了一个问题,我无法解决它。 我正在尝试根据一些代码制作计算器并出现此错误

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

这是代码

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(home: Home()));
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  TextEditingController pesoController = TextEditingController();
  TextEditingController alturaController = TextEditingController();
  String _info = "Informe seus dados";
  GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  void _reset() {
    setState(() {
      pesoController.text = "";
      alturaController.text = "";
      _info = "Informe seus dados";
    });
  }

  void _calculate() {
    double peso = double.parse(pesoController.text);
    double altura = double.parse(alturaController.text) / 100;
    double imc = peso / (altura * altura);

    setState(() {
      if (imc < 18.6) {
        _info = "Abaixo do Peso (${imc.toStringAsPrecision(2)})";
      } else if (imc >= 18.6 && imc <= 24.9) {
        _info = "Peso Ideal (${imc.toStringAsPrecision(2)})";
      } else if (imc >= 24.9 && imc <= 29.9) {
        _info = "Levemente acima do peso (${imc.toStringAsPrecision(2)})";
      } else if (imc >= 24.9 && imc <= 34.9) {
        _info = "Obesidade Grau I (${imc.toStringAsPrecision(2)})";
      } else if (imc >= 34.9 && imc <= 39.9) {
        _info = "Obesidade Grau II (${imc.toStringAsPrecision(2)})";
      } else if (imc >= 40) {
        _info = "Obesidade Grau III (${imc.toStringAsPrecision(2)})";
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Calculador IMC"),
        centerTitle: true,
        backgroundColor: Colors.deepPurple,
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.refresh),
            onPressed: _reset,
          )
        ],
      ),
      backgroundColor: Colors.white,
      body: SingleChildScrollView(
        padding: EdgeInsets.all(20),
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              Icon(Icons.person, size: 120, color: Colors.deepPurple),
              TextFormField(
                keyboardType: TextInputType.number,
                decoration: InputDecoration(
                    labelText: "Peso (KG)",
                    labelStyle: TextStyle(color: Colors.deepPurple)),
                textAlign: TextAlign.center,
                style: TextStyle(color: Colors.deepPurple, fontSize: 25),
                controller: pesoController,
                validator: (value) {
                  if (value!.isEmpty) {
                    return "Informe seu peso!";
                  }
                },
              ),
              TextFormField(
                keyboardType: TextInputType.number,
                decoration: InputDecoration(
                    labelText: "Altura (CM)",
                    labelStyle: TextStyle(color: Colors.deepPurple)),
                textAlign: TextAlign.center,
                style: TextStyle(color: Colors.deepPurple, fontSize: 25),
                controller: alturaController,
                validator: (value) {
                  if (value!.isEmpty) {
                    return "Informe sua altura!";
                  }
                },
              ),
              Padding(
                  padding: EdgeInsets.fromLTRB(0.0, 15, 0.0, 15),
                  child: Container(
                    height: 50,
                    child: RaisedButton(
                      onPressed: () {
                        if (_formKey.currentState.validate()) {
                          _calculate();
                        }
                      },
                      child: Text(
                        "Calcular",
                        style: TextStyle(color: Colors.white, fontSize: 25),
                      ),
                      color: Colors.deepPurple,
                    ),
                  )),
              Text(_info,
                  textAlign: TextAlign.center,
                  style: TextStyle(color: Colors.deepPurple, fontSize: 25))
            ],
          ),
        ),
      ),
    );
  }
}

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    解释如下。

    让我们考虑一下这适用于哪一行:

    _formKey.currentState.validate()
    

    消息

    不能无条件地调用方法“验证”,因为接收者可以是“空”。尝试使调用有条件(使用'?.')或向目标添加空检查('!')。

    表示“验证”之前的属性,即“currentState”,在某些情况下可能为空(https://dart.dev/null-safety 了解更多信息)。

    在实际为 null 的情况下,您不能调用“validate”方法,因为 null 没有“validate”方法。 也就是说,既然这样做了

    null.validate()
    

    是不行的,调用“validate”方法是(或者只能是,如果你有 null 安全激活) null 也是不行的:dart 试图告诉你你必须处理空值的情况。在 null-safety 之前,您可以编写它并且您可以在此案例的运行时找到。

    事实上,在运行时,“_formKey.currentState”可能是您所期望的对象,但在某些特定情况下它也可能为空。您必须决定如何处理:您是否 100% 确定在这种情况下“_formKey.currentState”不能为空?还是不确定?

    此时你有两个选择:

    1. 使用“null 断言运算符”(!.):手动告诉编译器此时调用“validate”方法是完全安全的,例如,因为您已经确定即使变量理论上可以为 null在某些情况下,您已经检查过了,并且该特定情况是 100% 安全的。换句话说,它在代码的特定点永远不会为空。 请注意,如果您错了,它会在运行时抛出错误 (Null check operator used on a null value)。
        _formKey.currentState!.validate();
    
    1. 使用“null 感知运算符”(?.):您不确定在这种情况下 currentState 是否可以为 null。你是在告诉你的编译器在后台写这个:
        if(_formKey.currentState != null) {
           _formKey.currentState.validate();
        }
    

    【讨论】:

      【解决方案2】:

      试试这样的:

      validator: (value) {
          if (value!.length < 1) return 'Empty field';
          return null;
      }
      

      【讨论】:

        【解决方案3】:

        只需添加“!”要么 '?'在 .validate() 之前。所以改变这一行:

        if (_formKey.currentState.validate()) {
        

        到:

        if (_formKey.currentState!.validate()) {
        

        这是因为 dart 2.0 中添加了空安全运算符。您可以在此链接中阅读更详细的内容:https://dart.dev/null-safety

        【讨论】:

          猜你喜欢
          • 2022-08-24
          • 2022-08-21
          • 2021-09-18
          • 2022-08-15
          • 1970-01-01
          • 2023-03-05
          • 1970-01-01
          • 2021-10-05
          • 1970-01-01
          相关资源
          最近更新 更多