为什么这个“案例”是必须的?

发布于 2024-10-19 04:30:32 字数 431 浏览 2 评论 0原文

object Test1 {
    def main(args: Array[String]) {
        val list = List("a", "b")
        list map { x ⇒ println(x) }
        list map { case x ⇒ println(x) }

        val list2 = List(("aa", "11"))
        list2 map {
            case (key, value) ⇒ println("key: "+key+", value: "+value)
        }
    }

}

请注意最后一行,为什么必须使用关键字 case,但 list map { x ⇒ println(x) } 可以去掉它?

object Test1 {
    def main(args: Array[String]) {
        val list = List("a", "b")
        list map { x ⇒ println(x) }
        list map { case x ⇒ println(x) }

        val list2 = List(("aa", "11"))
        list2 map {
            case (key, value) ⇒ println("key: "+key+", value: "+value)
        }
    }

}

Please note the last line, why the keyword case must be used, but the list map { x ⇒ println(x) } can remove it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

情话已封尘 2024-10-26 04:30:32

您无法在函数文字中打开元组。这就是为什么你必须使用大小写来匹配它们。另一种方法是使用 tupled 使具有两个参数的函数适合:

import Function.tupled 
list2 map tupled {
  (key, value) => println("key: "+key+", value: "+value)
}

You can't break open the tuple in function literal. That's why you'll have to use case to match them instead. Another way is using tupled to make your function with two arguments fit:

import Function.tupled 
list2 map tupled {
  (key, value) => println("key: "+key+", value: "+value)
}
月朦胧 2024-10-26 04:30:32
{ case (key, value) => f }

与第一个不同的是

{ (key, value) => f }

,模式匹配将 Tuple2 分解为其组件,并将它们的值分配给 keyvalue。在这种情况下,仅传递一个参数(元组)。 <代码>{ x => println(x) } 之所以有效,是因为 x 被分配了元组,并且 println 打印它。

第二个是一个带有两个参数的函数,并且不进行模式匹配。由于 map 需要一个采用单个参数的函数,因此第二种情况与 map 不兼容。

{ case (key, value) => f }

is not the same thing as

{ (key, value) => f }

The first is a pattern match that breaks a Tuple2 into its components, assigning their values to key and value. In this case, only one parameter is being passed (the tuple). { x => println(x) } works because x is assigned the tuple, and println prints it.

The second is a function which takes two parameters, and makes no pattern matching. Since map requires a function which takes a single parameter, the second case is incompatible with map.

ヤ经典坏疍 2024-10-26 04:30:32

list2 具有 Tuple2[Int, Int] 类型的元素,因此您必须传递 map 的函数签名(在本例中... foreach 是一个更自然的选择)是 Tuple2[Int, Int] =>单位。也就是说,它需要一个 Tuple2[Int, Int] 类型的参数。

由于 Tuple2 支持 unapply,因此您可以使用模式匹配在函数中分解该元组,就像您所做的那样:

{
  case (key, value) ⇒ println("key: "+key+", value: "+value)
}

该函数的签名仍然是 Tuple2[Int, Int] => Unit

它与 Scala 相同,并且可能编译为相同的字节码,如下所示:

{
  x: Tuple2[Int, Int] => println("key: "+x._1+", value: "+x._2)
}

这是 Scala 以非常令人愉快的方式组合正交概念的众多示例之一。

list2 has elements of type Tuple2[Int, Int], so the signature of the function you have to pass map (in this case ... foreach is a more natural choice when you don't return something) is Tuple2[Int, Int] => Unit. Which is to say, it takes a single argument of type Tuple2[Int, Int].

Since Tuple2 supports unapply, you can use pattern matching to break apart that tuple within your function, as you did:

{
  case (key, value) ⇒ println("key: "+key+", value: "+value)
}

The signature of this function is still Tuple2[Int, Int] => Unit

It is identical to, and probably compiles to the same bytecodes, as:

{
  x: Tuple2[Int, Int] => println("key: "+x._1+", value: "+x._2)
}

This is one of so many examples where Scala combines orthogonal concepts in a very pleasing way.

预谋 2024-10-26 04:30:32

list2 地图 { x => println(x) } 对我来说没有问题。如果您想要进行模式匹配(根据其结构将您的参数分成几个部分),您始终需要 case。或者,您可以这样写:

list2 map { x => println("key: "+x._1+", value: "+x._2) }

顺便说一句,map 应该用于转换另一个列表中的列表。如果您只想遍历列表中的所有元素,请使用 foreach 或进行理解。

list2 map { x => println(x) } works without problems for me. If you want to have pattern matching (splitting your argument in its parts according to its structure) you need always case. Alternatively you can write:

list2 map { x => println("key: "+x._1+", value: "+x._2) }

BTW, map should be used to transform a list in another one. If you just want to go through all elements of a list, use foreach or for comprehension.

轻拂→两袖风尘 2024-10-26 04:30:32

我仍在学习 Scala,但我相信发生的情况是您定义了一个带有一个参数的部分函数。当调用仅需要一个参数的方法(例如 List.map 或 List.foreach)时,您可以省略下划线或命名 val。

在闭包中省略 val 名称的示例:

val v = List("HEY!", "BYE!")
v.foreach { Console.println } // Pass partial function, automatically

这与以下内容相同:

val v = List("HEY!", "BYE!")
v.foreach { Console.println _ } // Pass partial function, explicitly

使用匿名 val:

val v = List("HEY!", "BYE!")
v.foreach { Console.println(_) } // Refer to anonymous param, explicitly

或使用命名 val:

val v = List("HEY!", "BYE!")
v.foreach { x => Console.println(x) } // Refer to val, explicitly

在闭包中,您使用一个部分函数(case 语句),该函数接受匿名变量并立即将其转换为元组绑定到两个单独的变量。

我想我搞砸了上面的一个片段。当我到达工作计算机时,我将在 REPL 中进行验证。

另外,请查看 Scala 中的函数柯里化 了解更多信息信息。

I am still learning Scala, but I believe what's happening is that you've defined a partial function taking one argument. When invoking methods such as List.map or List.foreach that only require one argument you can omit the underscore or named val.

Example ommitting val name in closure:

val v = List("HEY!", "BYE!")
v.foreach { Console.println } // Pass partial function, automatically

This is the same as:

val v = List("HEY!", "BYE!")
v.foreach { Console.println _ } // Pass partial function, explicitly

Using the anonymous val:

val v = List("HEY!", "BYE!")
v.foreach { Console.println(_) } // Refer to anonymous param, explicitly

Or using a named val:

val v = List("HEY!", "BYE!")
v.foreach { x => Console.println(x) } // Refer to val, explicitly

In your closure you use a partial function (the case statement) that takes an anonymous variable and immediately turns it into a tuple bound to two separate variables.

I imagine I goofed up on one of the snippets above. When I get to my work computer I will verify in the REPL.

Also, take a look at Function Currying in Scala for some more info.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文