Dart &引用;参数类型';字符串?';can';不能分配给参数类型';字符串'&引用;使用stdin.readLineSync()时

Dart &引用;参数类型';字符串?';can';不能分配给参数类型';字符串'&引用;使用stdin.readLineSync()时,dart,Dart,我是dart的新手。我不知道我犯了什么样的错误,但是这个代码不起作用。 这是一个简单的代码,只需阅读终端中的年龄,并说它是未成年人或超过18岁 import 'dart:io'; main(){ print("Entre com a sua idade: "); var input = stdin.readLineSync(); var idade = int.parse(input); if(idade >= 18){ print(&qu

我是dart的新手。我不知道我犯了什么样的错误,但是这个代码不起作用。 这是一个简单的代码,只需阅读终端中的年龄,并说它是未成年人或超过18岁

import 'dart:io'; 

main(){
  print("Entre com a sua idade: ");
  var input = stdin.readLineSync();
  var idade = int.parse(input);

  if(idade >= 18){
    print("É maior de idade");
  }else{
    print("É menor de idade");
  }
}
我得到了这个错误:

algoritmo01.dart:15:25:错误:无法将参数类型“String”分配给参数类型“String”,因为“String”可为null,而“String”不可为null。
var idade=int.parse(输入)

欢迎来到Dart。您所体验到的是新的空安全功能(Dart 2.12.0引入),默认情况下变量不能包含空值。这是静态检查的,因此即使在程序执行之前也会出现错误

在您的示例中,问题如下所示:

var input = stdin.readLineSync();
如果我们查看手册,我们可以看到此方法具有以下签名:

String? readLineSync (
    {Encoding encoding = systemEncoding,
    bool retainNewlines = false}
) 

String?
表示它是可为null的类型,因此允许包含任何字符串或null。如果类型改为
String
,则意味着结果只能是
String
,而不能是
null

这意味着您的变量
input
现在具有类型
String?
。如果您看一下示例的第二行,这个i(在2.12.0中介绍)就是一个问题:

var idade = int.parse(input);
由于
int.parse
的签名是:

int parse (

    String source,
    {int? radix,
    @deprecated int onError(
        String source
    )}

) 

它接受一个
字符串
(因此永远不能为
null
)。因此,不允许将
字符串?
作为参数提供给只处理
字符串的方法。如果方法采用
String?
并给它一个
String
,则可以使用相反的方法

那么对于这种情况我们能做些什么呢?嗯,您需要处理
null
的情况,或者告诉Dart,如果
input
null
,它应该使您的程序崩溃

所以你可以像这样处理它:

import 'dart:io';

void main() {
  print("Entre com a sua idade: ");
  var input = stdin.readLineSync();
  
  if (input != null) {
    var idade = int.parse(input);

    if (idade >= 18) {
      print("É maior de idade");
    } else {
      print("É menor de idade");
    }
  } else {
    print('Input was null!');
  }
}
正如您所看到的,即使
输入
在技术上仍然是
字符串?
类型,这也是允许的。但是Dart可以看到您的
if
语句将阻止
input
具有值
null
,因此只要您在该if语句中,它就会“升级”为
String

另一个解决方案是告诉Dart,它应该停止抱怨关于
input
的静态错误,并在编译代码时假设
input
String

import 'dart:io';

void main() {
  print("Entre com a sua idade: ");
  var input = stdin.readLineSync()!;
  var idade = int.parse(input);

  if (idade >= 18) {
    print("É maior de idade");
  } else {
    print("É menor de idade");
  }
}
(更改是在
readLineSync()
之后添加的

在这种情况下,Dart将添加自己的
null
-如果
stdin.readLineSync
提供了
null
值,则检查并崩溃程序。这是为了确保我们永远不会给
int.parse
一个空值,这可能会使您的代码在其他地方崩溃。通过添加
null
-检查我们在哪里得到可疑值,我们可以确保我们快速失败,并且失败的位置与我们预期的不同


您可以在这里阅读更多有关Dart中的空安全性的信息(也由Stephen链接):

通读它将解释此错误—非常详细的解释!