here is the code and when I run code it's print my result correctly but there is a null as result (in line 4) :
main() {
var ferrari = Car();
ferrari.armor = 85;
print(ferrari.armor);
}
class Car {
int? _armor;
int? get armor {
return _armor;
}
set armor(int? armor) {
if (armor != null && armor < 100) {
print(true);
} else {
print(false);
}
}
you have a variable that you give to it a custom getter and setter, so basically when you call the getter ferrari.armor it returns the _armor from your class, but since you see the _armor in your code will be always null because actaully you didn't give it any value in the setter, so it stays always null.
here propably what you wanted to do.
main() {
var ferrari = Car();
ferrari.armor = 85;
print(ferrari.armor);
}
class Car {
int? _armor;
int? get armor {
return _armor;
}
set armor(int? armor) {
if (armor != null && armor < 100) {
_armor = armor; // add this
print(true);
} else {
print(false);
}
}
}
In the set function, you need to set the _armor.
set armor(int? armor) {
if (armor != null && armor < 100) {
_armor = armor; // Set _armor to armor here.
print(true);
} else {
print(false);
}
}
Related
In main.dart I call Quiz's function getQuestionText and getQuestionAnswer, getQuestionText works as expected but the other doesn't work, if returns me always the first result of the list. I just placed a debugPrint() and as expected getQuestionText() prints the correct number, getQuestionAnswer() always print 0, how is that possible?
class Quiz {
int _questionNumber = 0;
List<Question> _questions = [
Question('Some cats are actually allergic to humans', true),
Question('You can lead a cow down stairs but not up stairs.', false),
];
void nextQuestion() {
if (_questionNumber < _questions.length - 1) {
_questionNumber++;
}
}
String getQuestionText() {
print('$_questionNumber'); // <-- print the correct number
return _questions[_questionNumber].questionText;
}
bool getQuestionAnswer() {
print('$_questionNumber'); // <-- always print 0
return _questions[_questionNumber].questionAnswer;
}
}
Here how I call the functions
void checkAnswer(bool userAnswer) {
bool correctAnswer = Quiz().getQuestionAnswer();
setState(() {
if (userAnswer == correctAnswer) {
// right answer
} else {
// wrong pick
);
}
quiz.nextQuestion();
});
}
The problem is that you always create a fresh instance of your class Quiz by calling bool correctAnswer = Quiz().getQuestionAnswer(); inside checkAnswer().
Try to store the Quiz instance ouside:
const myQuiz = Quiz();
void checkAnswer(bool userAnswer) {
bool correctAnswer = myQuiz.getQuestionAnswer();
setState(() {
if (userAnswer == correctAnswer) {
// right answer
} else {
// wrong pick
}
myQuiz.nextQuestion();
});
}
I try to make flutter null safety migration, I have this old code, that worked before null safety, but after upgrade I have some error when there is "null". How can I change this ?
error for bestMove : the non nullable local variable must be assigned before it can be used
errror for return ScoredMove(0, null); :
the argument null can"t be assigned to the parameter Position
Here is the code
class ScoredMove {
final int score;
final Position move;
const ScoredMove(this.score, this.move);
}
Position _findNextMove(MoveSearchArgs args) {
ScoredMove bestMove = _performSearchPly(
args.board, args.player, args.player, args.numPlies - 1);
return bestMove.move;
}
ScoredMove _performSearchPly(GameBoard board, PieceType scoringPlayer,
PieceType player, int pliesRemaining) {
List<Position> availableMoves = board.getMovesForPlayer(player);
if (availableMoves.isEmpty) {
return ScoredMove(0, null);
//the argument null can"t be assigned to the parameter Position
}
int score = (scoringPlayer == player)
? GameBoardScorer.minScore
: GameBoardScorer.maxScore;
ScoredMove bestMove;
for (int i = 0; i < availableMoves.length; i++) {
GameBoard newBoard =
board.updateForMove(availableMoves[i].x, availableMoves[i].y, player);
if (pliesRemaining > 0 &&
newBoard.getMovesForPlayer(getOpponent(player)).isNotEmpty) {
score = _performSearchPly(
newBoard, scoringPlayer, getOpponent(player), pliesRemaining - 1)
.score;
} else if (pliesRemaining > 0 &&
newBoard.getMovesForPlayer(player).isNotEmpty) {
// Opponent has no moves; player gets another turn.
score =
_performSearchPly(newBoard, scoringPlayer, player, pliesRemaining - 1)
.score;
} else {
score = GameBoardScorer(newBoard).getScore(scoringPlayer);
}
//bestMove error the non nullable local variable must be assigned before it can be used
if (bestMove == null ||
(score > bestMove.score && scoringPlayer == player) ||
(score < bestMove.score && scoringPlayer != player)) {
bestMove =
ScoredMove(score, Position(availableMoves[i].x, availableMoves[i].y));
}
}
return bestMove;
}
class MoveFinder {
final GameBoard initialBoard;
MoveFinder(this.initialBoard) : assert(initialBoard != null);
Future<Position> findNextMove(PieceType player, int numPlies) {
return compute(
_findNextMove,
MoveSearchArgs(
board: this.initialBoard,
player: player,
numPlies: numPlies,
),
);
}
}
You can't do
ScoredMove(0, null)
Because the move parameter is not allowed to be null. A possible solution is to make it nullable. You can do that by adding ? after the type, like
class ScoredMove { final int score; final Position? move;
const ScoredMove(this.score, this.move);
}
And for the other error you can try changing
ScoredMove bestMove;
to
ScoredMove? bestMove = null;
and also changing
return bestMove;
to
return bestMove!;
I am trying to access current value of map that is in class level method from outside the function.
//This is function for call back
fireAlaram(String message_map) {
Assistant(message_map).speak();
}
//this is the function that is in stateful class
void do_backgroundTask() {
var ke = todoBox.keys.cast<int>().toList();
if (ke.length > 0) {
for (var _k in ke) {
if (todoBox.get(_k)!.time.compareTo(DateTime.now()) >= 0) {
m.addAll(todoBox.get(_k)!.toMap());
}
}
if (m.length > 0) {
products = m.keys.toList();
products.sort();
setState(() {
t = products[0];
});
AndroidAlarmManager.oneShotAt(t, 1,fireAlaram(m[t])
);
}
}
}
I want to get value of map string value when key is t, it gives null error
I have a function that returns a String, but when I call this function, the app screen goes red and I get this error: Expected a value of type 'string' but got one of type 'int'.
Here is my function that returns a String:
checkProportion(String predominantGamete, String resultado) {
var countBrown = 0;
var countBlack = 0;
var countWhite = 0;
var proportionCamundongo =
'Proporção: ${countBrown}:${countBlack}:${countWhite}';
if (predominantGamete == 'recessiva_aa' &&
resultado.contains('A') &&
resultado.contains('P')) {
return countBrown += 1;
} else if (predominantGamete == 'recessiva_aa' &&
resultado.contains('A') &&
resultado.contains('pp')) {
return countBlack += 1;
} else if (predominantGamete == 'recessiva_aa' &&
resultado.contains('aa')) {
return countWhite += 1;
}
return proportionCamundongo;
}
Here is how I call the function:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
title: Text(
checkProportion(widget.predominant, widget.result),
),
),
How to solve this error?
Here is an image that shows the colors of each result:
The issue here is that you are returning early, not breaking the if statement, when you do something like return countBrown += 1;;
Try incrementing the counters, then using string interpolation to display the value:
String checkProportion(String predominantGamete, String resultado) {
int countBrown = 0;
int countBlack = 0;
int countWhite = 0;
if (predominantGamete == 'recessiva_aa' &&
resultado.contains('A') &&
resultado.contains('P')) {
countBrown += 1;
} else if (predominantGamete == 'recessiva_aa' &&
resultado.contains('A') &&
resultado.contains('pp')) {
countBlack += 1;
} else if (predominantGamete == 'recessiva_aa' &&
resultado.contains('aa')) {
countWhite += 1;
}
return 'Proporção: ${countBrown}:${countBlack}:${countWhite}';
}
I'd also recommend specifing the return type of the function (String), using the correct types for counters (int). That will help your compiler catch the issues as well.
It isn't my best work, and there is probably a better way to check for if a string contains all occurrence of multiple substrings, but here you go:
bool isColorContained(String resultado, Set<String> requirements) {
for(String requirement in requirements) {
if (!resultado.contains(requirement)) {
return false;
}
}
return true;
}
String checkProportion(String predominantGamete, String resultado) {
Map<ColorType, Set<String>> colorType = {
ColorType.brown: {'A', 'P'},
ColorType.black: {'A', 'pp'},
ColorType.white: {'aa'},
};
Map<ColorType, int> colorTypeCount = {
ColorType.brown: 0,
ColorType.black: 0,
ColorType.white: 0,
};
for(MapEntry<ColorType, Set<String>> entry in colorType.entries ) {
if(predominantGamete != 'recessiva_aa') continue;
bool contained = isColorContained(resultado, entry.value);
if(contained) {
int count = colorTypeCount[entry.key] ?? 0;
colorTypeCount[entry.key] = count + 1;
}
}
return 'Proporção: ${colorTypeCount[ColorType.brown]}:${colorTypeCount[ColorType.black]}:${colorTypeCount[ColorType.white]}';
}
Also, declare the ColorType enum:
enum ColorType {
brown, black, white
}
This will scale with as many colors and requirements you have, by adding to the ColorType enum, the colorType map, and the colorTypeCount map.
I just finished my nullsafe migration. I'm finding that wrapping code with a null check only sometimes removes the need for the nullcheck ! operator? E.g.,
class MyClass {
double divideBy4(double numerator) {
return numerator / 4;
}
double quarteredWorks(double? value) {
if (value != null)
return divideBy4(value); // <- no intellisense warning
else
return 0;
}
double quarteredDoesntWork(double? value) {
return divideBy4(value); // <- intellisense: "double? can't be assigned to double"
}
double? value;
double divideBy2() {
if (value != null)
return value / 2; // <- intellisense: "receiver can be null"
else
return .0;
}
}
EDIT
Changed my example to show an example of wrapping with a null check that works