Flutter 具有零安全性的颤振中的单粒子类
我有一个类,它使用工厂构造函数获取一些参数,如果实例为null,将创建一个新对象;如果不为null,则返回instance的值,因此我们始终接收相同的对象(Singleton)。在启用dart的空安全特性之前,我就是这样使用单例模式的Flutter 具有零安全性的颤振中的单粒子类,flutter,dart,dart-null-safety,Flutter,Dart,Dart Null Safety,我有一个类,它使用工厂构造函数获取一些参数,如果实例为null,将创建一个新对象;如果不为null,则返回instance的值,因此我们始终接收相同的对象(Singleton)。在启用dart的空安全特性之前,我就是这样使用单例模式的 class GuestUser extends User { static GeustUser _instance; factory GuestUser( {required String firstName, required
class GuestUser extends User {
static GeustUser _instance;
factory GuestUser(
{required String firstName,
required String lastName,
required String email,
required Address address,
required PaymentInfo paymentInfo}) {
if (_instance == null) {
_instance =
GuestUser._(firstName, lastName, email, address, paymentInfo);
}
return _instance;
}
现在启用空安全性后,出现以下错误:
The non-nullable variable '_instance' must be initialized.
Try adding an initializer expression.
如果不再需要(\u instance==null),也可以使用
如果我这样定义\u实例
:static late final GuestUser\u实例
那么我不能使用if(\u instance==null)
仅在需要时创建\u实例。因此,每次调用工厂构造函数时,我都必须删除if语句并创建一个新实例
如何解决这个问题并创建一个启用空安全性的单例类
我考虑了这个解决方案,用一个布尔变量跟踪实例:
static late final GeustUser _instance;
static bool _isInstanceCreated = false;
factory GuestUser(
{required String firstName,
required String lastName,
required String email,
required Address address,
required PaymentInfo paymentInfo}) {
if (_isInstanceCreated == false) {
_instance =
GuestUser._(firstName, lastName, email, address, paymentInfo);
}
_isInsanceCreated = true;
return _instance;
}
但是我想知道是否有一种方法可以做到这一点,而不需要定义新的变量,并且通过使用空安全性的特性,您的单例有点奇怪,因为您使用的参数只有在第一次调用它时才会使用。这不是一个很好的模式,因为如果您想为两个不同的来宾用户使用它,它会给您带来一些惊喜
在您的示例中,使用GuestUser?
作为\u实例的类型是有意义的。Dart中默认情况下不可为空不应被视为使用null
是不好的,您应该在有意义的地方使用null
(特别是如果我们可以防止引入bool
变量来指示是否设置了变量)。在您的示例中,\u实例
在第一次初始化之前为空
使用??=
运算符的示例。操作员将检查\u实例
是否为null
,如果是null
,则将变量分配给通过调用构造函数GuestUser创建的对象。此后,它将返回\u instance
的值。如果\u实例
已经有一个值(不是null
),则只返回该值,而不调用GuestUser.\u
构造函数
class GuestUser extends User {
static GuestUser? _instance;
factory GuestUser(
{required String firstName,
required String lastName,
required String email,
required Address address,
required PaymentInfo paymentInfo}) =>
_instance ??=
GuestUser._(firstName, lastName, email, address, paymentInfo);
}
如果使用更传统的单例,则可以在定义中创建实例的位置创建一个静态final
变量。但这不允许参数。如前所述,您的单例实际上很奇怪,因为通常您会执行以下操作:
class-Foo{
静态最终实例=Foo.uz();
福;
}
但是,您不能用参数来实例化它。为此,您可以这样做:
类栏{
静态条实例;
巴(国际一级);
工厂条形图fromInt(int i){
var bar=bar.Ui;
实例=bar;
返回杆;
}
void display()=>打印('Bar实例');
}
void main(){
final nullableBar=Bar.instance;
最终不可为NullBar=Bar.fromInt(0);
nullableBar!.display();//运行时错误,因为在Bar.fromMap(0)之前使用了Bar.instance
nonNullableBar.display();//无错误
}
您可以使用相同的传统方法创建单例。您只需将空安全运算符放在正确的位置
class MySingleton {
// make this nullable by adding '?'
static MySingleton? _instance;
MySingleton._() {
// initialization and stuff
}
factory MySingleton() {
if (_instance == null) {
_instance = new MySingleton._();
}
// since you are sure you will return non-null value, add '!' operator
return _instance!;
}
}
这很好,谢谢,但最好将映射传递给工厂,因为名称是fromMap,但传递的是int。这当然有效,但在本例中使用映射更好。@Morez最初我打算使用map
(这是常规模式),但为了使代码简短,我使用了int
。哎呀,我刚才注意到我正在使用fromMap
word。实际上我应该更改代码。哈哈。谢谢你的关注!