Dart单例私有静态变量_instance报LateInitializationError未初始化如何解决
报错原因
- 你给静态变量
_instance加了late修饰符,Dart中late变量在未初始化时被访问会直接抛出LateInitializationError,不会返回null。你在getInstance方法中判断_instance == null的时候,就已经触发了未初始化变量的访问,直接报错,根本走不到后续的赋值逻辑。 late只适合能百分百保证变量在第一次访问前一定会完成初始化的场景,不适合需要判空实现懒加载的场景。
解决方案
方案1:将变量改为可空类型(最小改动适配原有逻辑)
把_instance的late修饰符去掉,改为可空类型,修改后的类代码如下:
import 'package:firstpage/Product.dart'; class ShoppingBasketData { // 改为可空类型,不用late修饰 static ShoppingBasketData? _instance; late List<Product> _basketItems; ShoppingBasketData() { _basketItems = <Product>[]; } List<Product> get basketItems => _basketItems; set basketItems(List<Product> value) { _basketItems = value; } static ShoppingBasketData getInstance() { // 此时判断可空变量是否为null不会报错 if (_instance == null) { _instance = ShoppingBasketData(); } // 已经判空,用!强制解包即可 return _instance!; } }
方案2:使用Dart推荐的标准单例写法(更简洁可靠)
Dart的静态变量本身就是懒加载的,只有第一次访问时才会初始化,我们可以用私有命名构造函数+静态final变量的方式实现更规范的单例,避免空判断:
import 'package:firstpage/Product.dart'; class ShoppingBasketData { // 静态final变量,懒加载初始化 static final ShoppingBasketData _instance = ShoppingBasketData._internal(); late List<Product> _basketItems; // 私有命名构造函数,禁止外部随意创建实例 ShoppingBasketData._internal() { _basketItems = <Product>[]; } List<Product> get basketItems => _basketItems; set basketItems(List<Product> value) { _basketItems = value; } // 直接返回已经初始化的实例 static ShoppingBasketData getInstance() { return _instance; } // 也可以用factory构造函数的方式,调用更方便: // factory ShoppingBasketData() => _instance; }
内容的提问来源于stack exchange,提问作者Navid Shokoufeh
相关产品推荐
相关产品推荐

