必须初始化不可为 null 的变量“_database”
The non-nullable variable '_database' must be initialized
我正在使用 flutter 制作一个 Windows 应用程序,在使用 sqflite 制作数据库时,弹出此错误我不知道如何真正解决这个问题。
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class DatabaseHelper {
static final _dbName = 'Database.db';
static final _dbVersion = 1;
static final _tableName = 'my table';
static final columnId = '_id';
static final columnName = 'name';
DatabaseHelper._privateConstuctor();
static final DatabaseHelper instance = DatabaseHelper._privateConstuctor();
static Database _database;
Future<Database> get database async {
if (_database == null) {
_database = await _initiateDatabase();
}
return _database;
}
_initiateDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = join(directory.path, _dbName);
return await openDatabase(path, version: _dbVersion, onCreate: _onCreate);
}
Future _onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE $_tableName (
$columnId INTEGER PRIMARY KEY,
$columnName TEXT NOT NULL)
''');
}
Future<int> insert(Map<String, dynamic> row) async {
Database db = await instance.database;
return await db.insert(_tableName, row);
}
Future<List<Map<String, dynamic>>> queryAll() async {
Database db = await instance.database;
return await db.query(_tableName);
}
Future<int> update(Map<String, dynamic> row) async {
Database db = await instance.database;
int id = row[columnId];
return await db
.update(_tableName, row, where: '$columnId = ?', whereArgs: [id]);
}
Future<int> delete(int id) async {
Database db = await instance.database;
return await db.delete(_tableName, where: '$columnId = ?', whereArgs: [id]);
}
}
这是我用于数据库助手的代码....它在 _database 中显示如下错误:
The non-nullable variable '_database' must be initialized.
Try adding an initializer expression.
您的代码中存在两个问题,这两个问题均来自 Dart 2.12.0 版引入的新的默认不可空 (NNBD) 功能。这两个问题都可以在以下部分找到:
static Database _database;
Future<Database> get database async {
if (_database == null) {
_database = await _initiateDatabase();
}
return _database;
}
首先,在 Dart 2.12.0 中,Database
表示不允许 null
作为值的类型。在你的例子中,你定义了一个变量 _database
,它没有被初始化为任何值。所以这个变量的值将是 null
。但是 Database
不允许这样做。
相反,我们需要使用 Database?
类型,它允许我们指向 Database
对象或 null
:
static Database? _database;
Future<Database> get database async {
if (_database == null) {
_database = await _initiateDatabase();
}
return _database;
}
现在我们遇到了一个新问题:
A value of type 'Database?' can't be returned from the function 'database' because it has a return type of 'Future<Database>'
这样做的原因是 Dart 空安全特性在执行 if (_database == null)
时不会提升 class 字段。您可以在此处阅读更多相关信息以及原因:
要解决此问题,我们可以将您的代码重写为:
static Database? _database;
Future<Database> get database async =>
_database ??= await _initiateDatabase();
??=
运算符将检查 _database
是否为 null
,如果是,则将其设置为 await _initiateDatabase()
的值,然后 return _database
的新值。如果 _database
已经有一个值,它将只是 returned.
可以在此处找到 Dart 中的 null 感知运算符的良好列表:https://medium.com/@thinkdigitalsoftware/null-aware-operators-in-dart-53ffb8ae80bb
您可以在此处阅读更多关于默认情况下 Dart 不可为空的信息:
https://dart.dev/null-safety
奖金
我觉得你也应该改一下:
_initiateDatabase() async {
收件人:
Future<Database> _initiateDatabase() async {
由于我们不知道 _initiateDatabase
return 是哪种类型,因此 Dart 会假定它是 dynamic
,这不是您想要的。
也许这会对你有所帮助,
请flutter sdk修改如下
sdk: ">=2.12.0 <3.0.0"
=> sdk: ">=2.7.0 <3.0.0"
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class DatabaseHelper {
static final dbname = "myDatabase.db";
static final dbversion = 1;
static final tablename = "myTable";
static final columnId = "id";
static final columnName = "name";
DatabaseHelper._privateConstructor();
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
static Database? _database;
Future<Database?> get database async {
if (_database != null) {
return _database;
}
_database = await initiateDatabase();
return _database;
}
initiateDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = join(directory.path, dbname);
return await openDatabase(path, version: dbversion, onCreate: onCreate);
}
Future onCreate(Database db, int dbversion) async {
return await db.execute('''
CREATE TABLE $tablename ($columnId INTEGER PRIMARY KEY,
$columnName TEXT NOT NULL)
''');
}
Future<int> insert(Map<String, dynamic> row) async {
Database? db = await instance.database;
return await db!.insert(tablename, row);
}
Future<List<Map<String, dynamic>>> queryAll() async {
Database? db = await instance.database;
return await db!.query(tablename);
}
Future<int> update(Map<String, dynamic> row) async {
Database? db = await instance.database;
int id = row[columnId];
return await db!
.update(tablename, row, where: '$columnId=?', whereArgs: [id]);
}
Future<int> delete(int id) async {
Database? db = await instance.database;
return await db!.delete(tablename, where: '$columnId=?', whereArgs: [id]);
}
}
我正在使用 flutter 制作一个 Windows 应用程序,在使用 sqflite 制作数据库时,弹出此错误我不知道如何真正解决这个问题。
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class DatabaseHelper {
static final _dbName = 'Database.db';
static final _dbVersion = 1;
static final _tableName = 'my table';
static final columnId = '_id';
static final columnName = 'name';
DatabaseHelper._privateConstuctor();
static final DatabaseHelper instance = DatabaseHelper._privateConstuctor();
static Database _database;
Future<Database> get database async {
if (_database == null) {
_database = await _initiateDatabase();
}
return _database;
}
_initiateDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = join(directory.path, _dbName);
return await openDatabase(path, version: _dbVersion, onCreate: _onCreate);
}
Future _onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE $_tableName (
$columnId INTEGER PRIMARY KEY,
$columnName TEXT NOT NULL)
''');
}
Future<int> insert(Map<String, dynamic> row) async {
Database db = await instance.database;
return await db.insert(_tableName, row);
}
Future<List<Map<String, dynamic>>> queryAll() async {
Database db = await instance.database;
return await db.query(_tableName);
}
Future<int> update(Map<String, dynamic> row) async {
Database db = await instance.database;
int id = row[columnId];
return await db
.update(_tableName, row, where: '$columnId = ?', whereArgs: [id]);
}
Future<int> delete(int id) async {
Database db = await instance.database;
return await db.delete(_tableName, where: '$columnId = ?', whereArgs: [id]);
}
}
这是我用于数据库助手的代码....它在 _database 中显示如下错误:
The non-nullable variable '_database' must be initialized.
Try adding an initializer expression.
您的代码中存在两个问题,这两个问题均来自 Dart 2.12.0 版引入的新的默认不可空 (NNBD) 功能。这两个问题都可以在以下部分找到:
static Database _database;
Future<Database> get database async {
if (_database == null) {
_database = await _initiateDatabase();
}
return _database;
}
首先,在 Dart 2.12.0 中,Database
表示不允许 null
作为值的类型。在你的例子中,你定义了一个变量 _database
,它没有被初始化为任何值。所以这个变量的值将是 null
。但是 Database
不允许这样做。
相反,我们需要使用 Database?
类型,它允许我们指向 Database
对象或 null
:
static Database? _database;
Future<Database> get database async {
if (_database == null) {
_database = await _initiateDatabase();
}
return _database;
}
现在我们遇到了一个新问题:
A value of type 'Database?' can't be returned from the function 'database' because it has a return type of 'Future<Database>'
这样做的原因是 Dart 空安全特性在执行 if (_database == null)
时不会提升 class 字段。您可以在此处阅读更多相关信息以及原因:
要解决此问题,我们可以将您的代码重写为:
static Database? _database;
Future<Database> get database async =>
_database ??= await _initiateDatabase();
??=
运算符将检查 _database
是否为 null
,如果是,则将其设置为 await _initiateDatabase()
的值,然后 return _database
的新值。如果 _database
已经有一个值,它将只是 returned.
可以在此处找到 Dart 中的 null 感知运算符的良好列表:https://medium.com/@thinkdigitalsoftware/null-aware-operators-in-dart-53ffb8ae80bb
您可以在此处阅读更多关于默认情况下 Dart 不可为空的信息: https://dart.dev/null-safety
奖金
我觉得你也应该改一下:
_initiateDatabase() async {
收件人:
Future<Database> _initiateDatabase() async {
由于我们不知道 _initiateDatabase
return 是哪种类型,因此 Dart 会假定它是 dynamic
,这不是您想要的。
也许这会对你有所帮助, 请flutter sdk修改如下
sdk: ">=2.12.0 <3.0.0"
=> sdk: ">=2.7.0 <3.0.0"
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class DatabaseHelper {
static final dbname = "myDatabase.db";
static final dbversion = 1;
static final tablename = "myTable";
static final columnId = "id";
static final columnName = "name";
DatabaseHelper._privateConstructor();
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
static Database? _database;
Future<Database?> get database async {
if (_database != null) {
return _database;
}
_database = await initiateDatabase();
return _database;
}
initiateDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = join(directory.path, dbname);
return await openDatabase(path, version: dbversion, onCreate: onCreate);
}
Future onCreate(Database db, int dbversion) async {
return await db.execute('''
CREATE TABLE $tablename ($columnId INTEGER PRIMARY KEY,
$columnName TEXT NOT NULL)
''');
}
Future<int> insert(Map<String, dynamic> row) async {
Database? db = await instance.database;
return await db!.insert(tablename, row);
}
Future<List<Map<String, dynamic>>> queryAll() async {
Database? db = await instance.database;
return await db!.query(tablename);
}
Future<int> update(Map<String, dynamic> row) async {
Database? db = await instance.database;
int id = row[columnId];
return await db!
.update(tablename, row, where: '$columnId=?', whereArgs: [id]);
}
Future<int> delete(int id) async {
Database? db = await instance.database;
return await db!.delete(tablename, where: '$columnId=?', whereArgs: [id]);
}
}