1

是否有任何选项可以在 vavrs 集合上应用对象分解?

即来自scala的类似代码片段的东西:

val x = List(1, 2, 3)

val t = x match {
  case List(a, b, c) => (a, b, c)
}

(在本例中,我们将列表转换为元组)

我在这里看到了一些与我的案例类似的示例https://github.com/vavr-io/vavr/issues/1157但看起来当前的语法不同,甚至是不可能的。

4

2 回答 2

3

Vavr 列表与许多函数式程序一样,由头部(单个元素,称为 Cons)和尾部(另一个列表)组成,但可以匹配第一个元素(不是最后一个,除非通过反转列表)这将比 Scala/Haskell 更冗长。此外,虽然您可以 MATCH 前 3 个元素,但您只能捕获第一个:

var t = Match(x).of(
  Case($Cons($(), $Cons($(), $Cons($(), $()))), (a, tail) -> Tuple(a, tail.head(), x.get(2)))
);

模式匹配的 Vavr 文档及其限制

当前的 API 做出了妥协,即所有模式都匹配,但只分解了根模式。

编辑:如果您想要列表中的 3 个元素,那么您需要确保第三个元素之后的尾部是一个空列表(称为 Nil):

var t = Match(x).of(
  Case($Cons($(), $Cons($(), $Cons($(), $Nil()))), (a, tail) -> Tuple(a, tail.head(), x.get(2)))
);
于 2019-03-28T20:22:06.757 回答
1

JMPL是一个简单的 java 库,它可以使用 Java 8 的特性来模拟一些特性模式匹配。该库还支持解构模式

   Figure figure = new Rectangle();

   let(figure, (int w, int h) -> {
      System.out.println("border: " + w + " " + h));
   });

   matches(figure).as(
      Rectangle.class, (int w, int h) -> System.out.println("square: " + (w * h)),
      Circle.class,    (int r)        -> System.out.println("square: " + (2 * Math.PI * r)),
      Else.class,      ()             -> System.out.println("Default square: " + 0)
   );

   foreach(listRectangles, (int w, int h) -> {
      System.out.println("square: " + (w * h));
   });

解构类必须有一个或多个提取方法。它们必须被标记为注解@Extract。必须输出参数。由于原始类型的原始类型和包装器不能通过引用传递,我们必须使用包装器,例如 IntRef、FloatRef 等。

   @Extract
   public void deconstruct(IntRef width, IntRef height) {
      width.set(this.width);
      height.set(this.height);
   }      
于 2020-05-30T14:19:05.223 回答