【发布时间】:2021-04-18 19:33:42
【问题描述】:
所以我们正在使用 Vaadin。 Vaadin 带有一个Key 接口。我复制了它并删除了除CONTROL 键之外的所有条目(这里出于演示目的,我们没有复制实际代码中的类):
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
@FunctionalInterface
public interface VaadinKey extends Serializable {
VaadinKey CONTROL = VaadinKey.of("Control", "ControlLeft", "ControlRight");
//...
static VaadinKey of(String key, String... additionalKeys) {
Objects.requireNonNull(key);
if ("".equals(key)) {
throw new IllegalArgumentException("'key' cannot be empty");
}
List<String> keys = new ArrayList<>();
keys.add(key);
keys.addAll(Arrays.asList(additionalKeys));
return () -> keys;
}
List<String> getKeys();
default boolean matches(String key) {
return getKeys().contains(key);
}
static boolean isModifier(com.vaadin.flow.component.Key key) {
return Stream.of(VaadinKeyModifier.values())
.anyMatch(k -> k.matches(key.getKeys().get(0)));
}
}
该接口由KeyModifier 类实现,我也将其复制并剥离:
import java.util.List;
import java.util.stream.Stream;
public enum VaadinKeyModifier implements VaadinKey {
/**
* KeyModifier for "{@code Control}" key.
*/
CONTROL(VaadinKey.CONTROL)
//...
;
private final VaadinKey key;
VaadinKeyModifier(VaadinKey key) {
this.key = key;
}
@Override
public List<String> getKeys() {
return key.getKeys();
}
public static VaadinKeyModifier of(String key) {
return Stream.of(values()).filter(k -> k.matches(key)).findFirst()
.orElseThrow(IllegalArgumentException::new);
}
}
现在让我们尝试在 Kotlin 中使用它:
fun foo() {
val ctrl: VaadinKeyModifier = VaadinKeyModifier.CONTROL
}
这将无法编译,因为
类型不匹配:推断类型是 VaadinKey!但 VaadinKeyModifier 是预期的
(如果我在 IntelliJ 中 ctrl+单击它,它也会将我带到 VaadinKey 界面。)
我也试过
import com.[...].VaadinKeyModifier.CONTROL as CONTROL_MODIFIER
fun foo() {
val ctrl: VaadinKeyModifier = CONTROL_MODIFIER
}
结果相同。
现在有趣的是,直接使用VaadinKeyModifier.CONTROL 不会注册VaadinKeyModifier::CONTROL 的任何用法,而import 变体在导入中注册了一种用法(但这并不能防止编译错误)。
什么给了?
为什么会这样?
我该如何让它发挥作用?
【问题讨论】:
-
嘿抱歉问,
CONTROL(VaadinKey.CONTROL);在 VaadinKeyModifier 中究竟应该做什么?顺便说一句,当您调用VaadinKeyModifier.CONTROL时,它应该调用其父级的 CONTROL 属性,因为CONTROL(VaadinKey.CONTROL);实际上什么都不做 -
@ErfanDP 好吧,它应该定义一个名为
CONTROL的VaadinKeyModifier枚举常量,它以VaadinKey.CONTROL作为其构造函数参数。
标签: java kotlin enums compiler-errors type-inference