简体   繁体   English

为什么 vavr 的 Function1 不接受 Seq<parent> class 接受序列<child> ?</child></parent>

[英]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.

相关问题 功能参数类别 <Type> 不会接受类型的孩子 - Function parameter Class<Type> won't accept child of type <? extends A>不接受A的子类 - <? extends A> won't accept A's child classes 为什么我不能将Scala的Function1隐式转换为java.util.function.Function? - Why can't I implicit convert Scala's Function1 to java.util.function.Function? 为什么引用子类对象的父类类型引用变量无法访问子类的方法 - Why parent class type reference variable having reference to child class object can't access child class's Methods 为什么Spring不将地图注入到子Struts 2 Action类中,而是注入父对象? - Why isn't Spring injecting a map into a child Struts 2 Action class but parent's objects are injected? 在Java中如何使用接受其父类的Single函数处理所有子类 - In Java How to handle all the child class with Single function which accept Its Parent class 是否可以在一个类中同时实现scala.collection.Seq [T]和java.util.List [T] - Is it possible to implement both scala.collection.Seq[T] and java.util.List[T] in one class 如何在Java中执行Scala的Seq ++操作数 - How to do the Scala's Seq ++ operand in Java 将Scala Seq从Java传递到Scala函数 - Pass Scala Seq into Scala function from Java 具有抽象类的构造方法-不接受特定的构造方法 - Constructor with abstract class - won't accept specific
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM