为清晰起见,我想在Dart中使用命名参数.我应该怎么处理它们?

Kaf*_*ait 13 named-parameters required dart flutter

TL; DR:由于有意识的设计选择,命名参数是可选的.没有官方语言支持,有没有办法强制执行(并通知)所需的命名参数?


我发现在定义类时使用命名参数非常有用.以AbilityMMORPG 为例:

class Ability {

  final name;
  final effectDuration;
  final recast;            // wait time until next use
  // ...
}
Run Code Online (Sandbox Code Playgroud)

effectDuration并且recast两者都携带相同类型的信息(即持续时间),并且可能由相同的数据类型表示.很容易混淆哪个数字去哪里.但是,它们对于对象的正确性都是至关重要的信息,因此在实例化期间它们不会丢失.

我可以通过try-catch打破程序来强制执行这些参数的要求,但这对于使用该类并且不知道的人来说听起来不是很有趣(缺少阅读文档并直观地理解类的内容)他们是必需的.

是否有办法强制执行某些命名参数的要求,同时管理通知呼叫者所述要求和/或帮助他们正确使用它?

Gün*_*uer 26

包提供了@required一个由DartAnalyzer支持注释.

Flutter经常使用它并@required直接提供import 'package:flutter/foundation.dart'

foo({@required String name}) {...}

foo(); // results in static warning
Run Code Online (Sandbox Code Playgroud)

@required不检查传递的值是否是null,只是在调用站点上实际传递了一个值.要检查null您还可以使用assert()检查传递的值

class Ability {
  Ability(this.name, this.effectDuration, this.recast) : assert(name != null), assert(effectDuration != null), assert(recast != null);
  final name;
  final effectDuration;
  final recast;            // wait time until next use
  // ...
}    
Run Code Online (Sandbox Code Playgroud)

  • 值得补充的是,颤振具有不同的参数约定:始终使用命名参数. (3认同)

Sur*_*gch 8

尽管您可以foundation按照已接受的答案中的描述使用 flutter包,但是当我使用不需要了解 Flutter 的模型类时,我更喜欢直接使用meta包。这样它就不会对框架产生不必要的依赖。这允许您甚至在 Flutter 之外共享 Dart 代码。

添加到pubspec.yaml

dependencies:
  meta: ^1.1.7
Run Code Online (Sandbox Code Playgroud)

将其导入到您的类文件中:

import 'package:meta/meta.dart';
Run Code Online (Sandbox Code Playgroud)

@required在代码中使用注释:

class Person {
  String name;
  int age;

  Person({@required this.name, this.age,});
}
Run Code Online (Sandbox Code Playgroud)

所以name是必需的参数,但age不是。

final person = Person(name: 'Bob');
Run Code Online (Sandbox Code Playgroud)

更新:

在即将发布的 Dart 版本中,required默认情况下应添加关键字,因此根本不需要导入。


Dam*_*irR 6

从 2.12 开始,您可以使用具有空安全性的required关键字 (not @required)。也不需要导入任何额外的包。

在这个例子中,命名参数name是可选的,而effectDurationrecast是必需的。

class Ability {
  final name;
  final effectDuration;
  final recast;

  Ability({this.name, required this.effectDuration, required this.recast});
}
Run Code Online (Sandbox Code Playgroud)

更新pubspec.yaml,例如:

environment:
  sdk: ">=2.12.0-0  <3.0.0"
Run Code Online (Sandbox Code Playgroud)

参考:

  1. 声音零点安全
  2. @required 与新的 required 关键字相比如何?


rmt*_*zie 5

就在这里!

这是一个例子:

class Ability {
  final String name;
  final Duration effectDuration;
  final bool recast;

  Ability({
    @required this.name,
    this.effectDuration = new Duration(seconds: 1),
    this.recast = false,
  }): 
    assert(name != null),
    assert(effectDuration != null);
}
Run Code Online (Sandbox Code Playgroud)

您不必断言该名称不等于null,但这可能对您有用。

  • 在编译时,如果你不传递 `name:something`,它会抛出一个错误,但它不知道 `something` 是否为空。断言在运行时执行此操作,但仅用于调试构建(因此它不会减慢您的生产构建速度!) (2认同)