我使用Javaslang-2.1.0-alpha和它的Javaslang-match相当于进行一些对象分解.根据丹尼尔在"匹配奇特的方式"部分的博客文章:
Match(person).of( Case(Person("Carl", Address($(), $())), (street, number) -> ...) )
如果检索匹配两个通配符模式中值Address
成street
和number
,但例子甚至不编译.我后来意识到所有物体都必须包裹在原子模式中,即"卡尔"变成$("卡尔").这是在阅读了这个问题之后.
我按照更新的教程,但没有更新此示例.
我将示例更新为:
Person person = new Person("Carl", new Address("Milkyway", 42)); String result2 = Match(person).of( Case(Person($("Carl"), Address($(),$())), (street, number) -> "Carl lives in " + street + " " + number), Case($(), () -> "not found") ); System.out.println(result2);
从控制台输出判断,它编译但我的值没有正确匹配:
Carl lives in Carl Address [street=Milkyway, number=42]
很明显,street
包含卡尔和number
整个Address
物体.
当我尝试添加第三个lambda参数来捕获Carl时:
Case(Person($("Carl"), Address($(),$())), (name, street, number) -> "Carl lives in " + street + " " + number)
代码无法编译,lambda表达式获得带有以下错误文本的红色下划线:
The target type of this expression must be a functional interface
$_
在最新版本的javaslang-match中无法忽略值.所以我想匹配每个将返回三个lambda参数的原子模式,如上所述.
我需要一个了解这个库的人向我解释如何在最新版本中进行这个对象分解.
免责声明:我是Javaslang的创造者.
案例需要处理(String,Address) - > {...}.$()匹配任意值,但处理程序/函数只接收分解对象树的第一层.$()位于第二层.
规则:所有图层都与图案匹配,只有第一层传递给处理程序.
事实上,Match的第一个原型处理了任意树深度,但是所有可能的组合都会在引擎盖下生成方法 - 容易超出最大字节代码大小并且编译时间呈指数级扩展为无限.
当前版本的Match是我目前看到的唯一实用的Java方法.
更新:
请让我就这一主题提供更具象征性的更新.
我们区分
输入的对象图
该模式树传递给相符
对象图的分解对象
广告1)对象图
给定一个对象,通过遍历该对象的属性(分别为实例变量)来跨越对象图.值得注意的是,我们不禁止对象包含循环(例如包含自身的可变列表).
在Javaslang中,如何将对象分解为其部分是没有自然的方法.为此目的,我们需要一种所谓的模式.
对象图的示例:
Person <-- root / \ "Carl" Address <-- 1st level / \ "Milkyway" 42 <-- 2nd level
广告2)模式树
模式(实例)固有地定义了如何分解对象.
在我们的示例中,模式类型看起来像这样(简化泛型):
Pattern2> / \ Pattern0 Pattern2 / \ Pattern0 Pattern0
被调用的模式方法返回上述类型的实例:
Person(...) / \ $("Carl") Address(...) / \ $() $()
Javaslang的Match API执行以下操作:
Match实例将给定person
对象传递给第一个Case.
Case将person
对象传递给模式Person(...)
该Person(...)
图案检查,如果给定的对象person
的类型的Person
.
如果为真,则图案分解如果所述子图案的物体进入其部分(由元组代表),并检查$("Carl")
和Address(...)
匹配这些部件(递归地重复3)
如果为false,则Match将对象传递给下一个Case(参见2.)
如果模式是原子的,即它不能再分解对象,则检查相等性并且一直通知调用者返回匹配情况.
当匹配大小写得到模式匹配时,它会将对象图的第一级的分解对象传递给匹配大小写处理程序.
目前,Java的类型系统不允许我们以任何类型的方式将任意对象图/树级别的匹配对象传递给处理程序.
广告3)分解的对象
我们已经在2)中提到了上面的对象分解.特别是当我们给定对象的部分沿模式树发送时使用它.
由于我们上面提到的类型系统的限制,我们将对象的匹配过程与处理分解的部分的过程分开.
Java允许我们匹配任意对象图.我们不限于此处的任何级别.
但是,当一个对象成功匹配时,我们只能将第一层的分解对象传递给处理程序.
在我们的例子,这些分解物是name
与address
给定person
(不street
和number
).
我知道这对Match API的用户来说并不明显.
下一个Java版本之一将包含值对象和本机模式匹配!但是,该版本的模式匹配将完全限制在第一级.
Javaslang允许匹配任意对象图 - 但它有价格.处理程序确实只接收第一层分解的对象,这可能会令人困惑.
我希望以一种可以理解的方式回答这个问题.
- 丹尼尔