如何解决为什么vavr的Function1不能接受Seq <Parent>类接受Seq <Child>?
我将Java与vavr结合使用,并且我具有一个Function1,该函数接受Seq<Parent>
并返回String
。那个班级为什么不接受Seq<Child>
?似乎有些东西具有逆方差/协方差/不变性,但是我很难理解为什么它不能编译。这是我的代码:
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
}
}
相反,我得到了错误(来自IntelliJ):
apply (io.vavr.collection.Seq<Bar>) in Function1 cannot be applied to (io.vavr.collection.Seq<Foo>).
这个简单的例子似乎应该可以正常工作。我想念什么,为什么不起作用?
解决方法
我最终弄清楚了。可以归结为Vavr如何通过Seq接口处理方差。
Scala中的 Seq
是协变的,这意味着Seq<Child>
被视为Seq<Parent>
的子类。因此,上述问题在翻译成Scala时有效。
class Bar {}
class Foo extends Bar
val foos: Seq[Foo] = Seq(new Foo,new Foo,new Foo);
val bars: Seq[Bar] = foos;
但是,似乎vavr的Seq
接口是不变的,这意味着Seq<Parent>
和Seq<Child>
被视为单独的类。 Vavr的Seq
具有一种称为narrow()
的方法,可以使这些上行广播正常工作。这就是解决上述问题的方法。
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));
不确定为什么要用这种方式设计Vavr。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。