Flutter调用assets数据库时Non-nullable变量未初始化错误如何解决
问题原因
这两处报错均由Dart的空安全校验规则触发:Dart要求所有非空类型的变量,必须在声明时完成初始化,或明确向编译器说明该变量会在被使用前完成初始化。你代码中声明的static Database _database;是非空的Database类型,但没有赋初始值,也没有做延迟初始化声明,因此触发校验报错。
解决方法
这里提供两种适配空安全的修改方案:
方案1:将数据库变量声明为可空类型(更稳妥)
你原本的逻辑就是先判断_database是否为null再决定是否初始化,完全符合可空类型的使用场景,修改如下:
- 将
static Database _database;修改为static Database? _database;,声明该变量允许为空 - 在getter方法中返回非空结果时添加非空断言
!,告知编译器此时变量一定不为空
修改后的完整代码如下:
import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/services.dart'; import 'package:path/path.dart'; import 'package:sqflite/sqflite.dart'; class DatabaseHelper { static const _databaseName = "main.db"; static const _databaseVersion = 1; DatabaseHelper._privateConstructor(); static final DatabaseHelper instance = DatabaseHelper._privateConstructor(); // 声明为可空类型 static Database? _database; Future<Database> get database async { if (_database != null) return _database!; _database = await _initDatabase(); return _database!; } _initDatabase() async { String path = join(await getDatabasesPath(), _databaseName); if (!(await databaseExists(path))) { ByteData data = await rootBundle.load(join("assets", _databaseName)); List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); await File(path).writeAsBytes(bytes); } return await openDatabase(path, version: _databaseVersion); } }
方案2:添加late关键字(代码更简洁)
如果你可以保证_database在被访问前一定会完成初始化,可以用late关键字告知编译器延迟校验该变量的初始化状态,修改方式很简单,只需要将static Database _database;修改为static late Database _database;即可,其他代码不需要改动。
注意:如果使用late关键字但实际运行时变量未被初始化就被访问,会抛出运行时异常,本场景下因为getter逻辑会先完成初始化再返回,因此可以安全使用。
内容的提问来源于stack exchange,提问作者bahrulmaany
相关产品推荐
相关产品推荐

