gpt4 book ai didi

scala - 是否可以在 scala 匹配器中使用算术?

转载 作者:行者123 更新时间:2023-12-01 12:37:37 24 4
gpt4 key购买 nike

考虑代码:

def MatchSmth(someInt: Int, offset: Int = 1): Int  = {
someInt match {
case `offset` + 3 => 123123
case `offset` + 4 => 22
case `offset` + 5 => 123
case invalid => -1
}
}

编译错误: scala not found: value +
等效1:
def MatchSmth(someInt: Int, offset: Int = 1): Int  = {
if (someInt == offset + 3) 123123
else if (someInt == offset + 4) 22
else if (someInt == offset + 5) 123
else -1
}

等效2:
def MatchSmth(someInt: Int, offset: Int = 1): Int  = {
someInt match {
case v if v == `offset` + 3 => 123123
case v if v == `offset` + 4 => 22
case v if v == `offset` + 5 => 123
case invalid => -1
}
}

除了等价物 1 和等价物 2 之外,还有与此代码类似的东西吗?为什么 Scala 不允许在匹配器中进行这种构造(使用算术)?

最佳答案

技术原因

从技术上讲,Scala 不允许在其规范中使用它。这已在 answer from Suma 中进行了描述。 .

概念原因

从概念上讲,模式匹配的想法不是为 if-then-else 或求解方程提供一个很好的捷径,而是提供使用解构定义部分函数,​​类似于 Lisp .对于这个任务,Scala 使用所谓的“提取器”。

提取器与构造器相反。从技术上讲,Scala 使用“unapply”方法分解给定对象的各个部分。 Unapply 接受对象并返回一个 bool 值、一个可选的原子值或一个可选的元组。或者,还有 unapplySeq,它可以返回一系列值。 Scala 然后尝试将结果与给定的参数列表匹配。当匹配可能时,Scala 取消原子值或具有给定参数名称的元组部分。 (见 this paper 了解更多详情)

例子:

case class Pet(name: String, age : Int)
Pet("Polly", 86) match {
case Pet(name, _) => println(s"Hello ${name}")
}
// This will print: Hello Polly

Scala 将创建一个对象 Pet("Polly", 86) .然后它将将该对象提供给 match 之后定义的偏函数。 .该函数将调用 Pet.unapply(...)在该对象上检查结果是否为 Some(Tuple[Int,_]) .如果为真,它将绑定(bind)变量 name到该元组的第一个成员并使用 println 调用给定的操作功能。

Scala 只检查 unapply 的结果的形状.从理论上讲,它可以更加努力地尝试将 unapply 的结果与给定变量统一起来。这在您的示例中的简单情况下会有所帮助。但在更复杂的情况下,它会带来巨大的运行时间损失。理论上,统一甚至可以无限循环。

摘要(tl;博士)

Match 不是花哨的 if,而是使用解构。它没有在统一方面付出任何努力,而是采用“原样”的术语。这对于保持快速生成的代码是必要的。

关于scala - 是否可以在 scala 匹配器中使用算术?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28167487/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com