如何从SharedPreferences读取数据并存储为不可修改的常量?
错误原因
Dart 中 const 关键字用于修饰编译时常量,要求值在编译阶段就必须完全确定。而你从 SharedPreferences 读取数据是运行时的异步操作,编译阶段无法拿到实际返回值,因此触发报错。
实现方案
你需要的「仅读取一次、后续不可修改」的需求,不需要用 const 实现,用以下两种方案即可:
方案1:用 late final 定义全局/顶层变量
late final 修饰的变量仅允许赋值一次,赋值后就无法修改,完全匹配你的需求,示例代码如下:
// 定义变量 late final int index; void main() async { WidgetsFlutterBinding.ensureInitialized(); // 应用启动阶段一次性完成赋值 SharedPreferences sp = await SharedPreferences.getInstance(); // 建议添加默认值,避免强制解包遇到空值引发崩溃 index = sp.getInt('index') ?? 0; runApp(const MyApp()); } // 后续业务代码中直接读取即可,无法再修改index的值
方案2:单例类封装(更适合规范项目)
如果不想污染全局变量空间,可以用单例类封装所有 SharedPreferences 固定配置,示例代码如下:
class AppConfig { // 单例实现 static final AppConfig _instance = AppConfig._internal(); factory AppConfig() => _instance; AppConfig._internal(); // 只读配置项 late final int index; // 可扩展其他配置项,比如late final String userName; // 初始化方法,在应用启动时调用一次即可 Future<void> initSp() async { SharedPreferences sp = await SharedPreferences.getInstance(); index = sp.getInt('index') ?? 0; } } // 启动时初始化 void main() async { WidgetsFlutterBinding.ensureInitialized(); await AppConfig().initSp(); runApp(const MyApp()); } // 业务侧使用 print(AppConfig().index);
注意事项
- 仅编译期可确定的固定值才适合用
const修饰,比如const defaultPageIndex = 0 - 从 SharedPreferences 取值时建议添加 fallback 默认值,不要直接用
!强制解包,避免存储值不存在时触发崩溃
内容的提问来源于stack exchange,提问作者Ercan Tomaç
相关产品推荐
相关产品推荐

