我的目标是创建一个按钮,当您单击禁用的按钮时,它将打印特定的消息。但如果您不使用启用功能,它不会要求您在构造函数参数中提供特定消息。
假设我们有这门课
class Button {
final String label;
final bool enable;
final String disableMessage;
Button(
this.label, {
bool? enable,
String? disableMessage,
}) : assert(enable == null || disableMessage != null),
enable = enable ?? true,
disableMessage = disableMessage ?? '';
}
我尝试使用断言和条件值,但是当我调用它时
Button('name', enable: false);
它不会显示任何错误,因为这只是一个断言。
我正在寻找一种方法来实现这种行为
Button('name'); // Good
Button('name', enable: false); // Error displayed
Button('name', disabledMessage: 'Button disabled'); // Error displayed
Button('name', enable: false, disabledMessage: 'Button disabled'); // Good
当使用另一个参数时,有条件必需的参数是正确的方法吗?
如果您在启用断言的情况下进行编译(例如调试版本),则它不会显示任何错误,因为这只是一个断言。
assert
会抛出AssertionError
。这适用于像您这样的逻辑错误(即程序员因违反 API 合同而犯错)。
但是,如果您希望在所有构建类型中抛出错误,那么您可以明确地这样做。例如:
void alwaysAssert(bool condition, String message) {
if (!condition) {
throw AssertionError(message);
}
}
class Button {
...
Button(
this.label, {
bool? enable,
String? disabledMessage,
}) : enable = enable ?? true,
disabledMessage = disabledMessage ?? '' {
// Note that the function parameters shadow the member variables, so
// `enable` an `disabledMessage` here are the local function parameters.
alwaysAssert(
enable == null || disabledMessage != null, 'Your error message');
}
请注意,上面的代码是从现有的
assert
复制逻辑,因此如果您这样做 Button('name', enable: true)
将会抛出错误。我不知道这是否真的是你想要的。对于 Button('name', disabledMessage: 'Button disabled')
的情况,它也失败了。我想你实际上想要:
Button(
this.label, {
this.enable = true,
String? disabledMessage,
}) : disabledMessage = disabledMessage ?? '' {
alwaysAssert(!enable == (disabledMessage != null), 'Your error message');
}
但也可以考虑通过推导来使 API 对调用者来说更简单
enable
:
class Button {
final String label;
final String? _disabledMessage;
Button(
this.label, {
String? disabledMessage,
}) : _disabledMessage = disabledMessage;
bool get enable => _disabledMessage == null;
String get disabledMessage => _disabledMessage ?? '';
}
或者通过创建单独的构造函数:
class Button {
final String label;
final bool enable;
final String disabledMessage;
Button(this.label)
: enable = true,
disabledMessage = '';
Button.disabled(this.label, this.disabledMessage) : enable = false;
}
在 Flutter 中,您可以通过在构造函数定义中使用 required 关键字有条件地要求构造函数参数。这允许您根据条件强制指定参数。以下是如何实现此目标的示例:
假设您有一个 Flutter 小部件,其构造函数带有两个参数,但您希望根据条件需要其中一个参数。可以使用required关键字指定满足条件时该参数为必填项。这是一个代码示例:
class MyWidget extends StatelessWidget { final String parameter1; final String? parameter2; // Constructor with a conditional required parameter MyWidget({ required this.parameter1, this.parameter2, }) : assert((parameter2 == null) || (parameter2 != null && parameter1.isNotEmpty)); @override Widget build(BuildContext context) { return Container( // Your widget's content ); } }
在此示例中,参数 1 始终是必需的,但仅当满足特定条件时才需要参数 2。使用断言语句在构造函数中指定条件。在这种情况下,当parameter2不为null并且parameter1不为空时,parameter2是必需的。
通过使用这种方法,您可以根据您的特定需求有条件地在小部件的构造函数中强制执行所需的参数。