【问题标题】:Arg type 'String? Function(String)' & 'void? Function(String)' can't assigned to param type String? Function(String?)? and void? Function(String?)?参数类型'字符串?函数(字符串)'&'无效?函数(字符串)'不能分配给参数类型字符串?函数(字符串?)?和无效?函数(字符串?)?
【发布时间】:2021-10-28 03:16:33
【问题描述】:

在检查电子邮件值为空或不是我得到的错误时,我在飞镖中收到参数类型不可分配错误

参数类型void Function(String)不能赋值给参数类型void Function(String?)?

参数类型String? Function(String)不能赋值给参数类型'String? Function(String?)?

这些是验证器类,

class EmailFieldValidator {
static String? validate(String value) {
    return value.isEmpty ? 'Email can\'t be empty' : null;
  }

}

class PasswordFieldValidator {
  static String? validate(String value) {
    return value.isEmpty ? 'Password can\'t be empty' : null;
  }
}

这是给出错误的代码

 List<Widget> buildInputs() {
    return <Widget>[
      TextFormField(
        key: Key('email'),
        decoration: InputDecoration(labelText: 'Email'),
        validator: EmailFieldValidator.validate, //this gives string error mentioned above
        onSaved: (String value) => _email = value, //getting void error mention above 
      ),
      TextFormField(
        key: Key('password'),
        decoration: InputDecoration(labelText: 'Password'),
        obscureText: true,
        validator: PasswordFieldValidator.validate,  // getting string error mentioned above
        onSaved: (String value) => _password = value, //getting void error mention above 
      ),
    ];
  }

【问题讨论】:

  • 你对这些错误信息的理解是什么?
  • 我猜错误消息说它不允许将不可为空的值分配给可空类型,我尝试进行适当的更改,但没有像添加空检查(!)
  • 空检查不是问题。这是XFieldValidator.validate 函数本身的类型。您在这些函数中所做的任何事情都与错误无关,问题是它们的类型不正确。正如错误提示的那样,TextFormField 对其验证器的预期类型为String? Function(String?),因此您需要使用String? validate(String? value) 的函数签名来声明它。
  • 非常感谢@Alexander,我找到并解决了两者的错误
  • 我已将我的评论形式化为更充实的答案。希望我已经帮助您对这些错误的含义有所了解,并且从那里进行的修复应该是直截了当的。如果您有任何问题,请告诉我。

标签: flutter validation dart email-validation dart-null-safety


【解决方案1】:

你可能会返回一个空值而它不允许你在那里使用空值的问题。

尝试在value之后添加!

onSaved: (String value) => _email = value!, 
onSaved: (String value) => _password = value!, 

【讨论】:

  • 我尝试添加空检查,但它抛出 The '!' will have no effect because the receiver can't be null. Try removing the '!' operator.
【解决方案2】:

这是在 Null Safety 出现问题后面临的问题。我通常只是将它转换为字符串来使用它。有时它会给出错误,但不会给出可能会破坏您的应用程序的错误。

onSaved: (String? value) => _email = value as String,


static String? validate(String? value) {
String valueString = value as String;
// Do Your Usual thing over here like checking if it's empty}

【讨论】:

  • 感谢@kushalagrwal Alexander 刚刚向我解释了我犯了什么愚蠢的错误感谢您的贡献
  • 这种强制施法完全违背了零安全的目的。
  • @Alexander 那么使用空安全变量还是强制转换更好?
  • 是的,我知道,因此我确实提到这只是一个临时修复。因此它也会在点上给出错误。但是,是的,好点。
  • @Mithson 好吧,让我问你这个问题:为什么你认为 Flutter API 的设计使得onSaved 接受一个带有可选String 参数的函数。为什么他们不直接接受带有非可选 String 参数的函数?
【解决方案3】:

第一个错误

EmailFieldValidator.validatePasswordFieldValidator.validate 具有相同的类型:String? Function(String)。也就是说,它们都是以非可选String为参数,返回可选String的函数。

错误消息告诉您TextFormFieldvalidator 参数需要String? Function(String?)? 类型的函数。也就是说,一个可选函数(也就是说,如果你根本不需要任何验证器功能,你可以传递null),它本身接受一个可选的String参数,并返回一个可选的String

注意区别:验证器函数的参数不是可选的,但它们必须是可选的。因此,您需要更改它们的函数签名:

static String? validate(String? /* ⬅️ Notice this is now optional! */ value) { ... }

虽然有人可能会问:为什么不在这里使用 lambda,并推断类型?

第二个错误

错误类似。查看docs of TextFormField's constructor,我们看到onSaved参数的类型是FormFieldSetter&lt;String&gt;,其中FormFieldSetter is just a typealias代表void Function(T? newValue)。因此,onSaved 参数的解析类型为void Function(String? newValue)

您传递的 lambda 函数 (String value) =&gt; _password = value 采用非可选的 String 参数。注意不匹配。它需要接受一个可选参数,因为保存过程可能会产生一个null 值,而您需要处理它。

您如何处理null 取决于您,并且取决于您的要求。如果该字段不是必需的,您可能希望最终将 null 保存在数据库中(例如)。或者您可以替换一个默认值(尽管在这种情况下这没有意义)。或者你在极端情况下,如果你绝对确定你永远不会得到一个空值,你可以强制解开它。当然,这样做就好像你在对 Dart 说以下内容:

我非常确定这永远不会是null。如果是这样,天就要塌了,我还没有想出办法来处理它。事情显然没有按照我的预期进行。与其在这种行为不端的状态下继续前进,不如让我的应用程序崩溃并防止进一步的损坏

这是否可取,取决于您的问题领域。

【讨论】:

    猜你喜欢
    • 2021-09-20
    • 2022-01-21
    • 1970-01-01
    • 2021-10-21
    • 2021-10-13
    • 2021-09-04
    • 1970-01-01
    • 2021-12-20
    相关资源
    最近更新 更多