Тип аргумента "Строка?" не может быть назначен типу параметра String при использовании stdin.readLineSync ()

Я новичок в дротике. Я не знаю, какую ошибку совершил, но этот код не сработал. Это простой код, просто прочтите возраст в терминале и скажите, что он несовершеннолетний или старше 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?' допускает значение NULL, а String - нет. var idade = int.parse (ввод);


person Bruno Proença    schedule 18.03.2021    source источник
comment
Прочтите dart.dev/null-safety/understanding-null-safety It объясню эту ошибку   -  person Stephen    schedule 18.03.2021


Ответы (1)


Добро пожаловать в Дарт. То, что вы испытали, - это новая функция нулевой безопасности (представленная в 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, и поэтому он может содержать любую строку или 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, что он должен просто вывести вашу программу, если 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!');
  }
}

Как видите, это разрешено, даже если input технически все еще относятся к типу String?. Но Дарт видит, что ваш оператор if не позволит input иметь значение null, поэтому оно будет повышено до String, пока вы находитесь внутри этого оператора if.

Другое решение - сказать 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-check там, где мы получаем сомнительное значение, мы можем гарантировать, что мы терпим неудачу быстро и в том месте, где все было не так, как мы ожидали.

Вы можете узнать больше о нулевой безопасности в Dart здесь (также ссылка на Стивена): https://dart.dev/null-safety/understanding-null-safety

person julemand101    schedule 18.03.2021
comment
Красивое и подробное объяснение! - person Ruslanbek0809; 02.05.2021