place.placePosition空安全校验报错问题求助
解决place.placePosition空检查后仍报错的问题及代码优化
核心解决方法
问题出在Dart空安全的类型推断逻辑上:直接在if条件里检查place.placePosition != null后,编译器可能无法准确跟踪后续place.placePosition!的非空状态(尤其当place是可变对象时)。最稳妥的修复方式是提前把placePosition赋值给局部变量,让编译器明确其非空性:
for (PlacesRecord place in places) { // 提前赋值给局部变量,消除空安全推断歧义 final position = place.placePosition; if (position != null) { double lat2 = position.latitude; double lon2 = position.longitude; // 后续逻辑正常执行即可 } }
这样完全不需要用!强制拆包,从根源上避免空安全相关报错。
代码优化建议
原代码存在效率和逻辑瑕疵:比如每次循环都对listKm排序(时间复杂度高达O(n²logn)),用indexWhere匹配double值还可能出现精度误差。以下是重构后的高效版本:
import 'dart:math' as math; List<PlacesRecord> getPlacesMaximumDistance( List<PlacesRecord> places, LatLng userGeo, double maxDistance, ) { final lat1 = userGeo.latitude; final lon1 = userGeo.longitude; final radianCoeff = 0.017453292519943295; // 角度转弧度系数 final cos = math.cos; // 1. 筛选有效地点并保存对应距离 final validEntries = <(PlacesRecord, double)>[]; for (final place in places) { final position = place.placePosition; if (position == null) continue; final lat2 = position.latitude; final lon2 = position.longitude; // 哈维正弦公式计算两点距离 final a = 0.5 - cos((lat2 - lat1) * radianCoeff) / 2 + cos(lat1 * radianCoeff) * cos(lat2 * radianCoeff) * (1 - cos((lon2 - lon1) * radianCoeff)) / 2; final distance = 12742 * math.asin(math.sqrt(a)); final roundedDistance = double.parse(distance.toStringAsFixed(2)); if (roundedDistance <= maxDistance) { validEntries.add((place, roundedDistance)); } } // 2. 按距离从小到大排序 validEntries.sort((a, b) => a.$2.compareTo(b.$2)); // 3. 提取排序后的地点列表 return validEntries.map((entry) => entry.$1).toList(); }
优化细节:
- 将循环内重复排序改为一次性排序,时间复杂度从O(n²logn)降至O(nlogn),大幅提升性能
- 用元组绑定地点和距离,避免维护两个并行列表的繁琐和精度匹配问题
- 用
continue简化分支逻辑,代码可读性更高 - 提取常量并命名,提升代码可维护性
内容的提问来源于stack exchange,提问作者Yardo
相关产品推荐
相关产品推荐

