使用 stdin.readLineSync() 时"The argument type 'String?' can't be assigned to the parameter type '



我是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: 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);

欢迎来到Dart。您正在体验的是新的空安全功能(随 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?表示它是可为 null 的类型,因此允许包含任何 String 或 null。如果类型是String则意味着结果只能是String,而永远不会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

这需要String(因此永远无法null)。因此,不允许将String?作为参数提供给仅处理String的方法。相反的情况是允许的(如果方法需要String?并且您给它一个String)。

那么我们能做些什么来应对这种情况呢?好吧,您需要处理null的情况或告诉Dart,如果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在技术上仍然是String?型,这也是允许的。但是 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- 检查并崩溃程序,如果它确实给出了nullstdin.readLineSync。这是为了确保我们仍然不会给int.parse一个 null 值,这可能会使您的代码在其他地方崩溃。通过添加null-检查我们从哪里获得可疑值,我们可以确保我们快速失败,并且在事情不像我们预期的那样的地方失败。

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

公认的答案是正确的。但还有另一种替代解决方案。你可以像这样使用"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");
}
}

I**t 不是因为空安全吗? 正如我阅读的那样,要将从标准输出到int的字符串转换为int,您必须执行下一个操作:

import 'dart:io'; 
main(){
print("E**ntre com a sua idade: ");
//You use ?? to indicate "otherwise" and '0' to use 0 if it is null.
var input = stdin.readLineSync()??'0';
//Here you also add otherwise '0' if it is null
var idade = int.parse(input ?? '0');
if(idade >= 18){
print("É maior de idade");
}else{
print("É menor de idade");
}
}

相关内容

  • 没有找到相关文章

最新更新