为什么变量数量可变的记录组件在使用自定义构造函数时没有被推断出来?

huangapple go评论74阅读模式
英文:

Why is the variable arity record component not inferred with custom constructor?

问题

尝试使用 record 和记录组件编写一些代码。我正在使用变量稀有组件,并在自定义构造函数上遇到了编译时错误。

public record Break<R extends Record>(R record, String... notifications) {

    public Break(R record, String... notifications) {
        System.out.println("record: " + record + " and notifications: " + Arrays.toString(notifications));
        this.record = record;
        this.notifications = notifications;
    }

    // 编译错误:非规范记录构造函数必须委托给另一个构造函数
    public Break(R record) {
        System.out.println("record: " + record);
        this.record = record;
    }

    public Break() {
        this(null); // 这可以工作
        // 实际上,IntelliJ 建议使用未能编译的构造函数
    }

    public static void main(String[] args) {
        new Break<>().new Break<>();
    }
}

我想要理解的是,当通过另一个自定义构造函数调用时,如果没有为初始化提供任何组件,类似的构造函数是如何推断出来的。

英文:

Trying out some code with record and record components. I was making use of the variable rarity components and was struck with a compile-time error over a custom constructor.

public record Break&lt;R extends Record&gt;(R record, String... notifications) {

    public Break(R record, String... notifications) {
        System.out.println(&quot;record: &quot; + record + &quot; and notifications: &quot; + Arrays.toString(notifications));
        this.record = record;
        this.notifications = notifications;
    }

    // compile error: non canonical record constructor must delegate to another costructor
    public Break(R record) { 
        System.out.println(&quot;record: &quot; + record);
        this.record = record;
    }

    public Break() {
        this(null); // this works 
        // actually intelliJ suggests it uses the constructor that is not compiling
    }


    public static void main(String[] args) {
        new Break&lt;&gt;(new Break&lt;&gt;());
    }
}

What I am curious to understand is, how is the similar constructor inferred when invoked via another custom constructor without any components provided for initialization.

答案1

得分: 7

这与可变参数无关。所有记录构造函数链必须“底于”规范构造函数(可以使用紧凑形式指定),无论是否具有可变参数性质。这表现为每个非规范构造函数必须委托给另一个构造函数;最终这意味着链条在规范构造函数处底于。

你可以通过以下方式修复你的错误构造函数:

public Break(R record) {
    this(record);
}

但是,你甚至不需要声明这个构造函数,因为规范构造函数已经可以处理形如 new Break(r) 的调用了。

英文:

This has nothing to do with variable arity. All record constructor chains must "bottom out" in the canonical constructor (which may be specified using the compact form), variable arity or not. This manifests as a requirement that each non-canonical constructor must delegate to another constructor; eventually this means chains bottom out in at the canonical.

You can fix your bad constructor with:

public Break(R record) {
    this(record);
}

But, you don't even need to declare this constructor all, since the canonical constructor can handle calls of the form new Break(r) already.

huangapple
  • 本文由 发表于 2020年9月30日 14:04:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/64131753.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定