Scala Match Case 结构和遍历具有奇数项 cs 和 m 的列表?
Scala Match Case structure and traversing a List with odd terms cs and m?
我正在尝试理解这段代码here
def countChange(money: Int, coins: List[Int]): Int = (money, coins) match {
case (0, _) => 1
case (m, _) if m < 0 => 0
case (_, cs) if cs.isEmpty => 0
case (m, cs) => countChange(m - cs.head, cs) + countChange(m, cs.tail)
}
}
我无法理解 (0,_)
、(m,_)
、(_,cs)
和 (m,cs)
对,因为术语 m
和 cs
未定义在代码正文中。
遍历List的这个构造叫什么?一对匹配的模式?
正在递归遍历列表。此构造称为 pattern matching
你可以这样读:
If the tuple (money, coins)
is a tuple whose first value is 0
then return 1
ignore the second value of the tuple
If the tuple (money, coins)
is a tuple has a first value below 0
then return 0 ignore the second value of the tuple.
等等...
_
在模式匹配中用来简化我们不关心那个参数是什么,它可以是任何东西
Scala 中的模式匹配由对象的 unapply
方法支持,阅读更多内容 about extractors。这意味着对于每个 case
方法 unapply
将以元组 (money, coins)
作为参数调用,如果确定它是匹配项,它将相应的第一个值和第二个值传递给 case
个子句。
示例:
语句case (m, _) => ...
将导致调用Tuple2.unapply((money, coins))
备注
案例 class 已经为我们定义了 unapply
方法。这就是为什么你可以在模式匹配中使用它们 'out of the box'。 Tuple2
是个案 class.
这是一个模式匹配的例子,它被用来递归地遍历你的硬币列表。这是用注释重写的相同代码,重要的是要知道每个 case
语句匹配元组的一个可能模式,而 _
用于忽略元组的片段。
def countChange(money: Int, coins: List[Int]): Int = {
// Construct a tuple for pattern matching on
val tuple: (Int, List[Int]) = (money, coins)
tuple match {
// Check to see if money == 0
case (0, _) => 1
// m represents money, use a guard to check if m is negative
case (m, _) if m < 0 => 0
// cs represents coins, use a guard statement check for empty list
case (_, cs) if cs.isEmpty => 0
// Recursive step. Since the patterns are tried in order, we
// now know that if we make it to here m (money) is non-zero
// and non-negative, and we know that cs (coins) is a non-empty
// list. Now we can call the recursive function safely on
// the head of the list
case (m, cs) => countChange(m - cs.head, cs) + countChange(m, cs.tail)
}
}
这一结构通常用于同时匹配多个变量。在 match
的顶部,您会看到 (money, coins)
。这意味着它在 money
和 coins
的 对 上匹配。它没有名字,因为它是同时对两个值进行完美的普通匹配。
I cannot understand the pairs (0,_)
, (m,_)
, (_,cs)
and (m,cs)
because the terms m
and cs
are undefined in the body of the code.
这些术语是在代码中定义的。 case
定义了它们。这就是匹配和解构的意义所在。
(money, coins) match {
case (0, _) => 1 // If money == 0, then coins is ignored and we return 1
case (m, _) if m < 0 => 0 // m = money, coins is ignored. If m < 0, return 0
case (_, cs) if cs.isEmpty => 0 // money is ignored, cs = coins.
// If we have no coins, return 0.
case (m, cs) => countChange(m - cs.head, cs) + countChange(m, cs.tail)
// Otherwise, m = money, cs = coins. Recurse down the list with
// countChange(money - coins.head, coins) + countChange(money, coins.tail)
}
元组 (money, coins)
的原因是因为这些模式依赖于 money
和 coins
。您要么需要嵌套 match
s(丑陋),要么需要执行更丑陋的布尔逻辑才能复制这些语义。
我正在尝试理解这段代码here
def countChange(money: Int, coins: List[Int]): Int = (money, coins) match {
case (0, _) => 1
case (m, _) if m < 0 => 0
case (_, cs) if cs.isEmpty => 0
case (m, cs) => countChange(m - cs.head, cs) + countChange(m, cs.tail)
}
}
我无法理解 (0,_)
、(m,_)
、(_,cs)
和 (m,cs)
对,因为术语 m
和 cs
未定义在代码正文中。
遍历List的这个构造叫什么?一对匹配的模式?
正在递归遍历列表。此构造称为 pattern matching
你可以这样读:
If the tuple
(money, coins)
is a tuple whose first value is0
then return1
ignore the second value of the tupleIf the tuple
(money, coins)
is a tuple has a first value below0
then return 0 ignore the second value of the tuple.
等等...
_
在模式匹配中用来简化我们不关心那个参数是什么,它可以是任何东西
Scala 中的模式匹配由对象的 unapply
方法支持,阅读更多内容 about extractors。这意味着对于每个 case
方法 unapply
将以元组 (money, coins)
作为参数调用,如果确定它是匹配项,它将相应的第一个值和第二个值传递给 case
个子句。
示例:
语句case (m, _) => ...
将导致调用Tuple2.unapply((money, coins))
备注
案例 class 已经为我们定义了 unapply
方法。这就是为什么你可以在模式匹配中使用它们 'out of the box'。 Tuple2
是个案 class.
这是一个模式匹配的例子,它被用来递归地遍历你的硬币列表。这是用注释重写的相同代码,重要的是要知道每个 case
语句匹配元组的一个可能模式,而 _
用于忽略元组的片段。
def countChange(money: Int, coins: List[Int]): Int = {
// Construct a tuple for pattern matching on
val tuple: (Int, List[Int]) = (money, coins)
tuple match {
// Check to see if money == 0
case (0, _) => 1
// m represents money, use a guard to check if m is negative
case (m, _) if m < 0 => 0
// cs represents coins, use a guard statement check for empty list
case (_, cs) if cs.isEmpty => 0
// Recursive step. Since the patterns are tried in order, we
// now know that if we make it to here m (money) is non-zero
// and non-negative, and we know that cs (coins) is a non-empty
// list. Now we can call the recursive function safely on
// the head of the list
case (m, cs) => countChange(m - cs.head, cs) + countChange(m, cs.tail)
}
}
这一结构通常用于同时匹配多个变量。在 match
的顶部,您会看到 (money, coins)
。这意味着它在 money
和 coins
的 对 上匹配。它没有名字,因为它是同时对两个值进行完美的普通匹配。
I cannot understand the pairs
(0,_)
,(m,_)
,(_,cs)
and(m,cs)
because the termsm
andcs
are undefined in the body of the code.
这些术语是在代码中定义的。 case
定义了它们。这就是匹配和解构的意义所在。
(money, coins) match {
case (0, _) => 1 // If money == 0, then coins is ignored and we return 1
case (m, _) if m < 0 => 0 // m = money, coins is ignored. If m < 0, return 0
case (_, cs) if cs.isEmpty => 0 // money is ignored, cs = coins.
// If we have no coins, return 0.
case (m, cs) => countChange(m - cs.head, cs) + countChange(m, cs.tail)
// Otherwise, m = money, cs = coins. Recurse down the list with
// countChange(money - coins.head, coins) + countChange(money, coins.tail)
}
元组 (money, coins)
的原因是因为这些模式依赖于 money
和 coins
。您要么需要嵌套 match
s(丑陋),要么需要执行更丑陋的布尔逻辑才能复制这些语义。