Код-ревью Middle Dart: типы и null-safety обновлено
Код-ревью: работа с null и коллекциями
Вопрос
Функция считает сумму заказа и собирает названия товаров. Найдите проблемы.
double total(Order? order) {
var sum = 0.0;
for (var i = 0; i < order!.items.length; i++) {
sum += order.items[i].price! * order.items[i].qty;
}
return sum;
}
List<String> titles(List<Item> items) {
final result = items.map((i) {
analytics.log('title ${i.id}');
return i.title;
});
return result.toList() + result.toList();
}
bool sameCart(List<Item> a, List<Item> b) => a == b;
Коротко
Главные темы: ! переносит ошибку в рантайм, map ленивый и пересчитывается на каждом обходе, коллекции сравниваются по ссылке. Деньги в double стандартная претензия на любом ревью.
Что должен найти ревьюер
- Ошибкастрока 3
order!упадёт, если заказа нет. Тип параметра разрешаетnull, значит нужен явный ответ: вернуть 0 или сделать параметр ненулевым. - Ошибкастрока 4
price!прячет возможныйnullв цене: исключение в рантайме. Нужно решить, что делать с товаром без цены, или сделать поле ненулевым в модели. - Ошибкастрока 4Деньги в
doubleдают ошибки округления. Хранить в копейках (int) или десятичным типом. - Ошибкастрока 11Побочный эффект внутри ленивого
map: логирование выполнится при каждом обходе, здесь дважды на каждый товар. - Ошибкастрока 17
==у списков сравнивает ссылки: два одинаковых по содержимому списка не равны. НуженlistEqualsилиListEqualityиз пакета collection.
Разбор
Главные темы: ! переносит ошибку в рантайм, map ленивый и пересчитывается на каждом обходе, коллекции сравниваются по ссылке. Деньги в double стандартная претензия на любом ревью. Исправленная версия: int total(Order order) => order.items.fold(0, (s, i) => s + i.priceKopecks * i.qty);, логирование отдельным циклом, сравнение через listEquals.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.