gpt4 book ai didi

在 switch 表达式中尝试记录模式时出现 Java 19 编译器问题

转载 作者:行者123 更新时间:2023-12-05 02:26:25 25 4
gpt4 key购买 nike

我从这里下载了 JDK19 的候选发布版 https://jdk.java.net/19/尝试使用那里实现的新记录模式,但我遇到了一些问题。在我的测试中,我写了一个基于密封接口(interface)加记录的Optional版本,如下:

package tests.patterns;

import java.util.Objects;

public class TestRecordPatter
{
public static void main(final String[] args)
{
final Opt<String> opt1 = computeAnswer(23);
final String answer1 = switch (opt1) {
case Opt.Some<String>(String ans) -> ans;
case Opt.None __ -> "no answer";
default -> throw new IllegalStateException("This should not happen"); // A
};
System.out.println(answer1);

final Opt<String> opt2 = computeAnswer(35);
final Object answer2 = switch (opt2) { // B
case Opt.Some<String>(var ans) -> ans; // C
case Opt.None __ -> "no answer";
default -> throw new IllegalStateException("This should not happen"); // A-2
};
System.out.println(answer2);

final Opt<String> opt3 = computeAnswer(84);
final String answer3 = switch (opt3) { // D
case Opt.Some<String> s -> s.value();
case Opt.None __ -> "no answer";
};
System.out.println(answer3);
}

private static Opt<String> computeAnswer(final int question)
{
if (question % 2 == 0) {
return Opt.some(String.valueOf(question / 2));
} else {
return Opt.none();
}
}

private sealed interface Opt<T> permits Opt.Some, Opt.None
{

static <T> Opt<T> of(final T value)
{
return value == null ? none() : some(value);
}

static <T> Opt<T> some(final T value)
{
return new Opt.Some<>(value);
}

@SuppressWarnings("unchecked")
static <T> Opt<T> none()
{
return Opt.None.NONE;
}

record Some<T>(T value) implements Opt<T>
{

public Some
{
Objects.requireNonNull(value, "Value must not be null");
}
}

@SuppressWarnings({ "rawtypes" })
enum None implements Opt
{
NONE;
}
}
}

第一个 switch 表达式使用记录解构来使用 ans 变量的显式类型从 Some 变体中获取值,但在这种情况下,java 编译器需要默认分支(标记为A) 否则失败并出现以下错误:

TestRecordPatter.java:[10,40] the switch expression does not cover all possible input values

在第二个开关中,问题是使用 var 而不是 ans 的显式类型会将开关的返回类型绑定(bind)到 Object而不是 String。 (标有 B 的行)。此外,但这不是 Java 编译器问题,IntelliJ 在标记为 C 的行上提示,突出显示 var ans 部分并说“需要类型 T 但提供了 null”之类的话。

最后,第三个开关工作正常,但这是“旧的”(java 17 是旧的,对吧?)方式。

有人可以帮助我吗?我做错了什么吗?

编辑:我刚刚下载了 Oracle JDK-19 GA 版本,它有同样的问题。

编辑 2:第二个开关,带有 var 的开关与第一个开关具有相同的行为,因此它需要一个默认情况,正如 Holger 所指出的那样

最佳答案

Am I doing something wrong?

是也不是。您正在假设枚举和密封类型如何交互(以及常量 case 标签),如果您来自 Haskell,这些假设是有意义的,但 Java 尚未 catch 。具体来说,枚举的穷尽检查仅限于切换该枚举类型,因此当枚举类型用作密封类型的允许子类型时,枚举值的穷举尚未被视为穷尽允许的子类型。这是因为常量大小写标签尚未被视为模式,而是按照它们的旧含义处理。在穷举中混合常量大小写标签和密封类型是将来会出现的事情(回想一下这仍然是一个预览功能。)

与此同时,以下工作正常:

sealed interface Opt<T> { ... }

record Some<T>(T t) implements Opt<T> { }
record None<T>() implements Opt<T> { }

我明白您为什么要使用枚举,并且在适当的时候该举措会奏效,但现在还没有。

关于在 switch 表达式中尝试记录模式时出现 Java 19 编译器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73787918/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com