Ошибка Error: A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't
void main() {
var bob = User('Bob', 20, true, ['footbal', 'Skate']);
// ..name = 'Bob'
// ..age = 40;
bob.info();
var alex = User('Alex', 25, false, ['Basketbol']);
}
class User{
String? name;
int? age;
bool? isHappy;
List<String>? hobbies;
User(name, age, [ishappy, hobbies]){
this.name = name;
this.age = age;
this.isHappy = isHappy;
this.hobbies = hobbies;
}
void info(){
var happy = isHappy ? 'happy' : 'not happy';
print('User $name is $age years old. He is $happy. His hobbies:');
for(var el in hobbies){
print(el);
}
}
}
ошибка:
Error compiling to JavaScript:
Info: Compiling with sound null safety
lib/main.dart:25:17:
Error: A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
var happy = isHappy ? 'happy' : 'not happy';
^
lib/main.dart:27:19:
Error: The type 'List<String>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<String>?' is nullable and 'Iterable<dynamic>' isn't.
- 'List' is from 'dart:core'.
- 'Iterable' is from 'dart:core'.
for(var el in hobbies){
^
Error: Compilation failed.
делаю код тут: https://dartpad.dartlang.org/?
Я в программировании зеленый, подскажите, пожалуйста, в чем может быть проблема.
Ответы (1 шт):
В чем ошибка?
var happy = isHappy ? 'happy' : 'not happy';
В сообщении об ошибке говориться о том, что компилятор не может привести переменную типа bool? к bool
И если вы заметили то в списке полей у Вас указан тип с вопросительным знаком:
bool? isHappy;
Что это вопросительный знак значит?
Данный знак что данная переменная опциональная.
Это значит что
- она может быть и тогда в ней будет значение типа
bool, - а может не быть и тогда в ней будет значение null
Т.е. она может принимать одно из трех значений:
- true
- false
- null
Но, это не входит в планы остальных языковых конструкций.
- Они знают как себя вести с
true - Они знают как себя вести с
false - А что делать когда у тебя
nullони не знают
Подробнее узнать об этом можно в оффициальной документации: https://dart.dev/null-safety/understanding-null-safety
Поэтому компилятор ругается на Вас, чтобы Вы могли разрешить конфликт и объяснить ему что делать в том случае когда перемення будет равна null, чтобы снять с себя за это ответственность.
Начиная с Dart 2.0 - это ваша ответственность.
Какие могут быть варианты?
Вариант №1: мы точно знаем что там не будет null
Первый вариант - это не разрешает вышеуказанную неопределенность.
Первый вариант заключается в том, что вы пообещаете компилятору что данной неопределенности не будет.
Если мы наверняка знаем что в данном участке кода данная переменная 100% будет определена - мы можем сообщить об этом компилятору поставив !(восклицательный знак) после переменной.
var happy = isHappy! ? 'happy' : 'not happy';
таким образом мы говорим компилятору: "Не боись, под мою ответственность! Там 100 пудов не будет null. Мы его пятью строками ранее определили."
И компилятору этого достаточно, чтобы пропустить Вас дальше...ну а если приложение таки ляжет - то это будет ваша вина ¯\_(ツ)_/¯ .
Вариант №2: А пёс её знает...но если вдруг встретишь null, то считай его...
Второй вариант это разрешить данную неопределенность указав в коде какое значение необходимо подставить, если вдруг в переменной будет null.
Делается это через два ??(два вопросительных знака) после имени переменной, после которых вы указываете дефолтное значение(по умолчанию).
var happy = (isHappy ?? false) ? 'happy' : 'not happy';
В данном случае мы указываем что если переменная isHappy не будет определена - мы будем использовать false и результат этого выражения в свою очередь идет в тернарный оператор.
Также стоит отметить, что Вы используете в коде далеко не одну опциональную переменную. Вы также пытаетесь распечатать переменную hobbies.
И её также стоит обработать:
В первом случае:(точно без null)
for(var el in hobbies!) {
Во втором случае (если null, то используем пустой список):
for(var el in (hobbies ?? [])) {
Ошибка №2
Это к слову не единственная ошибка.
Есть еще одна небольшая помарочка в конструкторе
User(name, age, [ishappy, hobbies]){
this.name = name;
this.age = age;
this.isHappy = isHappy;
this.hobbies = hobbies;
}
Присмотритесь внимательнее:
- в параметрах вы используете переменную
ishappy(все с маленькой), - а в теле конструктора используете
isHappy(H c большой)
Причем это довольно коварная ошибка ибо isHappy также имеется и чисто технически компилятор это пропустит. Вы просто будете сохранять в поле его же значение, а значение из параметров конструктора никогда не дойдет до назначения...
Это нужно исправить:
User(name, age, [ishappy, hobbies]){
this.name = name;
this.age = age;
this.isHappy = ishappy;
this.hobbies = hobbies;
}
Итоговый вариант:
(я предпочту второй вариант, т.к он более надежный)
Что и Вам рекомендую
void main() {
var bob = User('Bob', 20, true, ['footbal', 'Skate']);
bob.info();
var alex = User('Alex', 25, false, ['Basketbol']);
alex.info();
}
class User{
String? name;
int? age;
bool? isHappy;
List<String>? hobbies;
User(name, age, [ishappy, hobbies]){
this.name = name;
this.age = age;
this.isHappy = ishappy;
this.hobbies = hobbies;
}
void info(){
var happy = (isHappy ?? false) ? 'happy' : 'not happy';
print('User $name is $age years old. He is $happy. His hobbies:');
for(var el in (hobbies ?? [])){
print(el);
}
}
}
