我有这样一个类,它通过使用工厂构造函数来获取一些参数,如果instance为null,将创建一个新对象;如果不为null,则将返回instance的值,因此我们总是收到相同的对象(Singleton)。这就是我在启用dart的空安全特性之前使用单例模式的方式。
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;
}现在启用了null-safety,我得到了这个错误:
The non-nullable variable '_instance' must be initialized.
Try adding an initializer expression.此外,不再需要if (_instance == null)。
如果我像这样定义_instance:static late final GuestUser _instance;,那么我就不能只在需要时使用if (_instance == null)来创建_instance。因此,我必须删除if语句,并在每次调用工厂构造函数时创建一个新实例。
如何解决这个问题并创建一个启用了null-safety的单例类?
我在脑海中有一个解决方案,用一个布尔变量来跟踪实例:
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;
}但是我想知道是否有一种方法可以在不定义新变量的情况下,通过使用null-safety的特性来实现这一点。
发布于 2021-03-07 04:30:37
你的单例有点奇怪,因为你接受的参数只会在第一次被调用时使用。这不是一个很好的模式,因为如果你想为两个不同的访客用户使用它,它会给你带来一些惊喜。
在您的示例中,只使用GuestUser?作为_instance的类型是有意义的。在Dart中,默认情况下不可为空的情况不应该被视为null的糟糕用法,您应该明确地在有意义的地方使用null (特别是如果我们可以防止引入bool变量来指示是否设置了变量的话)。在您的示例中,_instance在第一次初始化之前为null。
我们使用??=运算符的示例。操作符将检查_instance是否为null,如果是null,它将把变量赋给通过调用构造函数GuestUser._创建的对象。此后,它将返回_instance的值。如果_instance已经有一个值(不是null),那么这个值将不会调用GuestUser._构造函数而直接返回。
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);
}如果您有一个更传统的单例,您可以在定义中创建实例的位置创建一个static final变量。但这不允许参数。
发布于 2021-05-18 21:54:42
正如@julemand101提到的,你的单例实际上很奇怪,因为通常你会这样做:
class Foo {
static final instance = Foo._();
Foo._();
}但是,您不能使用参数实例化它。为此,您可以执行以下操作:
class Bar {
static Bar? instance;
Bar._(int i);
factory Bar.fromInt(int i) {
var bar = Bar._(i);
instance = bar;
return bar;
}
void display() => print('Bar instance');
}
void main() {
final nullableBar = Bar.instance;
final nonNullableBar = Bar.fromInt(0);
nullableBar!.display(); // Runtime error as Bar.instance is used before Bar.fromMap(0)
nonNullableBar.display(); // No error
}发布于 2021-06-09 17:52:11
您可以使用相同的传统方法来创建单例。您只需将空安全操作符放在正确的位置。
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!;
}
}https://stackoverflow.com/questions/66510201
复制相似问题