7

我是飞镖的新手。我不知道我犯了什么样的错误,但是这段代码不起作用。是一个简单的代码,只需在终端中读取年龄并说它是未成年人或超过 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: Error: The argument type 'String?' can't be assigned to the parameter type 'String' because 'String?' is nullable and 'String' isn't.
  var idade = int.parse(input);
4

3 回答 3

12

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

在您的示例中,问题是以下行:

var input = stdin.readLineSync();

如果我们查看手册,我们可以看到此方法具有以下签名:

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

https://api.dart.dev/stable/2.12.2/dart-io/Stdin/readLineSync.html

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

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

var idade = int.parse(input);

由于的签名int.parse是:

int parse (

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

) 

https://api.dart.dev/stable/2.12.2/dart-core/int/parse.html

这需要 a String(因此永远不会是null)。因此,您不能将您的String?as 参数提供给仅处理String. 相反的情况是允许的(如果方法采用String?并且你给它 a String)。

那么对于这种情况我们能做些什么呢?好吧,你需要处理或者告诉 Dart 如果是null,它应该让你的程序崩溃。inputnull

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

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!');
  }
}

正如您所看到的,即使input在技术上仍然是 type也是允许的String?。但是 Dart 可以看到,您的if语句将阻止input具有该值,因此只要您在此 if 语句中null,它就会被“提升” 。String

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

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 将添加自己的-check 并在确实给出值null时使程序崩溃。这是为了确保我们仍然永远不会给出可能使您的代码在其他地方崩溃的空值。通过在我们得到可疑值的地方添加-check,我们可以确保我们快速失败并且在事情与我们预期不同的地方失败。stdin.readLineSyncnullint.parsenull

你可以在这里阅读更多关于 Dart 中的 null-safety(也由 Stephen 链接):https ://dart.dev/null-safety/understanding-null-safety

于 2021-03-18T18:23:46.580 回答
0

公认的答案是正确的。但是还有另一种替代解决方案。您可以像这样使用“if null”运算符:

var idade = int.parse(input ?? "-1");

所以完整的代码看起来像这样:

import 'dart:io'; 

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

  if(idade >= 18){
    print("É maior de idade");
  }else if(idade < 18 && idade > 0){
    print("É menor de idade");
  } else {
    print("entrada errada");
  }
}
于 2021-08-28T23:33:31.177 回答
0

细绳?表示它可能是字符串或空值。但是,我们需要将一个非空值传递给int.parse. 错误说那个字符串?可以为空,但 String 不是。

要修复此错误,您需要在尝试解析值之前检查 null。

使用tryParse()方法而不是int.parse()

void main() {
  var yourValue = stdin.readLineSync();

  if(yourValue != null){
    var parsedValue = int.tryParse(yourValue);
  }
}

parse()和有什么区别tryParse()

parse()为无效的输入字符串抛出 aFormatException为无效的输入字符串 tryParse()返回 null

于 2022-01-25T03:50:31.070 回答