[英]Why won't vavr's Function1 accepting Seq<Parent> class accept Seq<Child>?
I'm using Java with vavr and I have a Function1 that accepts a Seq<Parent>
and returns a String
.我将 Java 与 vavr 一起使用,我有一个 Function1 接受Seq<Parent>
并返回一个String
。 Why won't that class accept Seq<Child>
?为什么 class 不接受Seq<Child>
? It seems like something with contravariance/covariance/invariance, but I am having trouble working through why it won't compile.这似乎是具有逆变/协方差/不变性的东西,但我无法解决为什么它无法编译。 Here is my code:这是我的代码:
interface Bar {
String getFoo();
}
class Foo implements Bar {
private String foo;
private String bar;
@Override
public String getFoo() {
return foo;
}
public Foo(String foo, String bar) {
this.foo = foo;
this.bar = bar;
}
}
class Scratch {
public static void main(String[] args) {
Function1<Seq<Bar>, String> myFunction = (it) -> "foo";
Foo obj = new Foo("foo", "bar");
Foo obj1 = new Foo("hello", "world");
Seq<Foo> list = List.of(obj, obj1);
String result = myFunction.apply(list); // IntelliJ says this line is incorrect
}
}
Instead, I get the error (from IntelliJ):相反,我得到了错误(来自 IntelliJ):
apply (io.vavr.collection.Seq<Bar>) in Function1 cannot be applied to (io.vavr.collection.Seq<Foo>).
This simple example seems like it should work just fine.这个简单的例子看起来应该可以正常工作。 What am I missing and why doesn't it work?我错过了什么,为什么它不起作用?
I ended up figuring it out.我最终弄清楚了。 This can be boiled down to how Vavr handles variance with the Seq interface.这可以归结为 Vavr 如何处理与 Seq 接口的差异。
Seq
s in Scala are covariant, meaning Seq<Child>
is treated like a subclass of Seq<Parent>
. Scala 中的Seq
是协变的,这意味着Seq<Child>
被视为Seq<Parent>
的子类。 Thus, the above problem when translated into Scala works.因此,上述问题在翻译成 Scala 时有效。
class Bar {}
class Foo extends Bar
val foos: Seq[Foo] = Seq(new Foo, new Foo, new Foo);
val bars: Seq[Bar] = foos;
However, it seems the vavr's Seq
interface is invariant, meaning Seq<Parent>
and Seq<Child>
are treated as separate classes.但是,似乎 vavr 的Seq
接口是不变的,这意味着Seq<Parent>
和Seq<Child>
被视为单独的类。 Vavr's Seq
has a method called narrow()
to make these upcasts work properly. Vavr 的Seq
有一个名为narrow()
的方法来使这些向上转换正常工作。 That is how to solve the problem above.这就是解决上述问题的方法。
class Scratch {
public static void main(String[] args) {
Function1<Seq<Bar>, String> myFunction = (it) -> "foo";
Foo obj = new Foo("foo", "bar");
Foo obj1 = new Foo("hello", "world");
Seq<Foo> list = List.of(obj, obj1);
String result = myFunction.apply(Seq.narrow(list));
Not sure why Vavr is designed this way.不知道为什么 Vavr 是这样设计的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.