";成语;Scala中模式匹配的定义
我尝试使用Scala已经有一段时间了,我非常喜欢它,但是很多时候,当我使用它时,我总是担心我没有“正确”地使用它,即使在这种情况下,它产生了正确的结果。 请考虑此代码:";成语;Scala中模式匹配的定义,scala,Scala,我尝试使用Scala已经有一段时间了,我非常喜欢它,但是很多时候,当我使用它时,我总是担心我没有“正确”地使用它,即使在这种情况下,它产生了正确的结果。 请考虑此代码: val list1 = List(0, 0, 0, 1) val list2 = List(0, 0, 0, 2) val list3 = List(0, 0, 1, 2) val list4 = List(0, 0, 0, 0) def numCheck(listToCheck: List[Int]): String = {
val list1 = List(0, 0, 0, 1)
val list2 = List(0, 0, 0, 2)
val list3 = List(0, 0, 1, 2)
val list4 = List(0, 0, 0, 0)
def numCheck(listToCheck: List[Int]): String = {
listToCheck match {
case l if l.contains(1) => "Contains a one"
case l if l.contains(2) => "Contains a two, but no ones"
case _ => "Contains no ones or twos"
}
}
println(numCheck(list1))
println(numCheck(list2))
println(numCheck(list3))
println(numCheck(list4))
输出为:
Contains a one
Contains a two, but no ones
Contains a one
Contains no ones or twos
这是一个问题的简化版本的解决方案,我使用完全相同的方法解决了这个问题,并且输出是正确的
我想知道的是模式匹配是否是正确的方法?如果是,是否可以进一步简化?Scala是否有更适合解决此问题的语言特性?
我之所以怀疑自己,是因为我的解决方案与我在学习语言时看到的许多例子都不一样——我把几乎所有的逻辑都放在了警卫中
如果有人能为我指出一些专注于模式匹配的学习资源,我也会很高兴
谢谢。我觉得你写的没问题,尽管你引入了这个新的标识符
l
,这对listToCheck
是多余的,因为它们总是一样的。我会避免那样做
这里有一些其他的选择。我不确定他们中是否有人特别地道
- 将
定义为函数而不是方法。我认为这是表达这段代码的最干净的方式,但是如果您需要将其作为一种方法,那么您可能无法摆脱它numCheck
val numCheck: List[Int] => String = { case l if l.contains(1) => "Contains a one" case l if l.contains(2) => "Contains a two, but no ones" case _ => "Contains no ones or twos" }
- 使用if-else链。这可能是“最简单”的方法,但它的缺点是有点难看,因为案例排列得不是很好
def numCheck(l: List[Int]): String = if (l.contains(1)) "Contains a one" else if (l.contains(2)) "Contains a two, but no ones" else "Contains no ones or twos"
- 匹配一个伪值
并在每种情况下都将其丢弃(()匹配{…
)。这感觉有点滥用case{…
语法,但它确实为您提供了一个很好的案例一致性Match
def numCheck(listToCheck: List[Int]): String = () match { case _ if listToCheck.contains(1) => "Contains a one" case _ if listToCheck.contains(2) => "Contains a two, but no ones" case _ => "Contains no ones or twos" }
离题: 你没问,只是出于好奇,哈斯克尔的样子会和你一样
- 这:
numCheck list | elem 1 list = "Contains a one" | elem 2 list = "Contains a two, but no ones" | otherwise = "Contains no ones or twos"
- 或者这个:
numCheck list | elem 1 list = "Contains a one" numCheck list | elem 2 list = "Contains a two, but no ones" numCheck _ = "Contains no ones or twos"
- 或使用多路if扩展:
:set -XMultiWayIf numCheck list = if | elem 1 list -> "Contains a one" | elem 2 list -> "Contains a two, but no ones" | otherwise -> "Contains no ones or twos"
sequence $ putStrLn . numCheck <$> [[0,0,0,1], [0,0,0,2], [0,0,1,2], [0,0,0,0]]
sequence$putStrLn.numCheck[[0,0,0,1],[0,0,0,2],[0,0,1,2],[0,0,0,0]]
有趣!所以当将numCheck定义为一个函数时,匹配是隐式的?我发现,当我尝试对一个未编译的方法使用相同的方法时(“无法解析符号包含”)。这正是我要寻找的指针类型,谢谢!如果没有match
关键字,模式匹配表达式的类型为Function
或PartialFunction
,具体取决于上下文。在上面的示例中,上下文要求Function[List[Int],String]是的,你可以把它看作是把{case…}
分解成x=>x匹配{case…}
。我不记得它是否是这样定义的。我知道人们有时会避免if
/else
链太多。对我来说,这就是这里的变体。