【问题标题】:Constructors in dart [duplicate]飞镖中的构造函数[重复]
【发布时间】:2026-01-14 12:20:04
【问题描述】:

我的班级中有这个构造函数。现在当它是这样的时候,我得到了

The type parameter icon is annotated with @required
but only named parameters without default value can be annotated with it.

-

const Category(
    @required this.name,
    @required this.icon,
    @required this.color
  ) : assert(name != null),
      assert(icon != null),
      assert(color != null);

当这样调用构造函数时:

        Category(name: _categoryName, icon: _categoryIcon, color: _categoryColor),

这是一个错误。

当我用 {} 包围我的构造函数参数时,所有这些都消失了。

这是什么意思?

【问题讨论】:

  • 这不仅适用于构造函数,也适用于函数

标签: dart flutter


【解决方案1】:

{} 缺少使它们成为命名参数

const Category({
    @required this.name,
    @required this.icon,
    @required this.color
  }) : assert(name != null),
      assert(icon != null),
      assert(color != null);

或者只是删除@required

没有{},它们是无论如何都需要的位置参数。

Category('foo', someIcon, Colors.white)

Category(name: 'foo', icon: someIcon, color: Colors.white)

[] 使它们成为可选的位置参数。

位置(非可选)需要先声明,可选参数在最后。

可选的位置参数和可选的命名参数不能一起使用。

可选参数(位置和命名)可以有默认值

this.name = 'foo'

默认值需要是编译时常量。

【讨论】:

  • 那么命名参数是否意味着我必须用名字来称呼它们?此外,我对所需装饰器的理解是,它使不传递参数成为错误,这对我来说似乎很简单,我喜欢防御性地强迫自己坚持下去。我的理解正确吗?
  • 查看我的更新答案
【解决方案2】:

您使用了命名的可选参数,但您的构造函数接受了位置可选参数。

命名可选参数{}:

  1. 用于省略/避免参数并提高可读性。
  2. 参数位置无关紧要,因为使用名称引用。
  3. 由于您可以避免使用该参数,因此要表示该参数是必需的,请使用@required。大多数情况下,此注释用于说明这是无法避免的(如通知)。

const Category({
    @required this.name,
    @required this.icon,
    @required this.color
  }) : assert(name != null),
      assert(icon != null),
      assert(color != null);

//Category(name: _categoryName, icon: _categoryIcon, color: _categoryColor),

位置可选参数[]:

  1. 也用于避免或省略 args。
  2. 无法提及名称,因为它没有可读性(作为布尔参数的示例)。
  3. 论据立场很重要。
  4. 不需要@required,因为我们必须提供参数。

const Category(
    this.name,
    this.icon,
    this.color
  ) : assert(name != null),
      assert(icon != null),
      assert(color != null);

//Category(_categoryName, _categoryIcon, _categoryColor),

Read more from this SO answer.

【讨论】:

    【解决方案3】:

    @required 暗示一些值应该作为参数传递给这个参数,即使它只是默认值。

    此提示仅在与可选参数一起使用时才有意义,例如当您将参数用大括号括起来时,因为否则参数无论如何都是必需的(就像您在 java 中习惯的那样。

    在这里命名有点不幸,但 dart 中的 named 参数也意味着它们是可选的,你可以在没有它们的情况下调用函数。

    【讨论】:

    • 如果我说我明白这一点,那我就是在撒谎:)。为什么命名参数同时是可选的。我以为我已经过了争论令人困惑的地步,但是 Dart 出现了:)。谢谢你的回答埃德曼。
    • 它们(总是)是可选的,因为 namedpositional 参数是定义 optional 参数的两种可用语法。而 required 参数总是只是位置 列在最前面。 From Functions docs:The required parameters are listed first, followed by any optional parameters. Named optional parameters can also be marked as @required.