"参数类型'String?'不能分配给参数类型“字符串"";使用 stdin.readLineSync() 时 [英] "The argument type 'String?' can't be assigned to the parameter type 'String'" when using stdin.readLineSync()

查看:17
本文介绍了"参数类型'String?'不能分配给参数类型“字符串"";使用 stdin.readLineSync() 时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

i'm new at dart. I don't know what kind of mistake i have made, but this code didn't work. Is a simple code, just read the age in terminal and say it's underage or over 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' 不是.var idade = int.parse(input);

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 引入),默认情况下变量不能包含值空值.这是静态检查的,因此即使在执行程序之前您也会收到错误.

Welcome to Dart. What you are experience is the new null-safety feature (introduced with Dart 2.12.0) where variables by default cannot contain the value null. This is statically checked so you will get an error even before your program are executed.

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

In your example the problem is the following line:

var input = stdin.readLineSync();

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

If we check the manual we can see this method have the following signature:

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

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

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

String? means it is a nullable type and is therefore allowed to contain any String or null. If the type instead was String it would mean the result can only be a String and never null.

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

This means that your variable input now has the type String?. This (introduced with 2.12.0) is a problem if you take a look at the second line of your example:

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).

Which takes a String (which can therefore never be null). You are therefore not allowed to give your String? as parameter to a method which only handles String. The opposite would have been allowed (if method takes String? and you give it a String).

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

So what can we do about this situation? Well, you need to handle the case of null or tell Dart that it should just crash your program if input are 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!');
  }
}

如您所见,即使 input 在技术上仍然属于 String? 类型,这也是允许的.但是 Dart 可以看到您的 if 语句将阻止 input 具有值 null 因此它将被提升"到 String 只要你在这个 if 语句中.

As you can see, this is allowed even if input are technically still of the type String?. But Dart can see that your if statement will prevent input to have the value null so it will be "promoted" to String as long as you are inside this if-statement.

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

Another solution is to tell Dart that it should stop complain about statically errors about input and just assume input is String when compiling the code:

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()之后添加了!)

(The change is the ! added after readLineSync())

在这种情况下,如果 stdin.readLineSync 确实给出了 null 值,Dart 将改为添加自己的 null-检查并崩溃程序.这是为了确保我们永远不会给 int.parse 一个空值,这可能会使您的代码在其他地方崩溃.通过在我们得到可疑值的地方添加 null-check,我们可以确保我们快速失败,并且在事情不像我们预期的那样的地方失败.

Dart will in this case instead add its own null-check and crash the program if stdin.readLineSync does give a null value. This is to ensure that we are still never going to give int.parse a null value which could make your code crash somewhere else. By adding the null-check where we get the questionable value, we can ensure we fails fast and at the place where things was not as we expected it to be.

您可以在此处阅读有关 Dart 中空安全的更多信息(也由 Stephen 链接):https://dart.dev/null-safety/understanding-null-safety

You can read a lot more about null-safety in Dart here (also linked to by Stephen): https://dart.dev/null-safety/understanding-null-safety

这篇关于"参数类型'String?'不能分配给参数类型“字符串"";使用 stdin.readLineSync() 时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆