简体   繁体   English

向Scala添加“case”关键字背后的原因是什么?

[英]What's the reasoning behind adding the “case” keyword to Scala?

Apart from: 除了:

case class A

... case which is quite useful? ......非常有用的案例

Why do we need to use case in match ? 为什么我们需要在match使用case Wouldn't: 岂不:

x match {
  y if y > 0 => y * 2
  _ => -1
}

... be much prettier and concise? ... 漂亮和简洁?

Or why do we need to use case when a function takes a tuple? 或者为什么我们需要在函数取元组时使用case Say, we have: 说,我们有:

val z = List((1, -1), (2, -2), (3, -3)).zipWithIndex

Now, isn't: 现在,不是:

z map { case ((a, b), i) => a + b + i }

... way uglier than just: ...... 方式不仅仅是:

z map (((a, b), i) => a + b + i)

...? ...?

First, as we know, it is possible to put several statements for the same case scenario without needing some separation notation, just a line jump, like : 首先,正如我们所知,可以为同一个案例场景放置几个语句,而不需要一些分离符号,只需一行跳转,如:

x match {
       case y if y > 0 => y * 2
                          println("test")
                          println("test2")  // these 3 statements belong to the same "case"
}

If case was not needed, compiler would have to find a way to know when a line is concerned by the next case scenario. 如果不需要case ,编译器必须找到一种方法来了解下一个案例场景何时涉及到一行。

For example: 例如:

x match {
   y if y > 0 => y * 2
   _ => -1
}

How compiler would know whether _ => -1 belongs to the first case scenario or represents the next case? 编译器如何知道_ => -1属于第一种情况还是代表下一种情况?

Moreover, how compiler would know that the => sign doesn't represent a literal function but the actual code for the current case ? 此外,编译器如何知道=>符号不代表文字函数,而是当前case的实际代码?

Compiler would certainly need a kind of code like this allowing cases isolation: (using curly braces, or anything else) 编译器当然需要一种这样的代码允许案例隔离:(使用花括号或其他任何东西)

x match {
    {y if y > 0 => y * 2}
    {_ => -1}  // confusing with literal function notation
}

And surely, solution (provided currently by scala) using case keyword is a lot more readable and understandable than putting some way of separation like curly braces in my example. 当然,使用case关键字的解决方案(目前由scala提供)比在我的示例中使用像花括号这样的分离方式更具可读性和可理解性。

Adding to @Mik378's answer: 添加到@ Mik378的答案:

When you write this: (a, b) => something , you are defining an anonymous Function2 - a function that takes two parameters. 当你写这个: (a, b) => something ,你正在定义一个匿名的Function2 - 一个带有两个参数的函数。

When you write this: case (a, b) => something , you are defining an anonymous PartialFunction that takes one parameter and matches it against a pair. 当你写这个: case (a, b) => something ,你正在定义一个匿名的PartialFunction ,它接受一个参数并将它与一对匹配。

So you need the case keyword to differentiate between these two. 所以你需要case关键字来区分这两者。

The second issue, anonymous functions that avoid the case , is a matter of debate: 第二个问题是避免这种case匿名函数,这是一个有争议的问题:

https://groups.google.com/d/msg/scala-debate/Q0CTZNOekWk/z1eg3dTkCXoJ https://groups.google.com/d/msg/scala-debate/Q0CTZNOekWk/z1eg3dTkCXoJ

Also: http://www.scala-lang.org/old/node/1260 另外: http//www.scala-lang.org/old/node/1260

For the first issue, the choice is whether you allow a block or an expression on the RHS of the arrow. 对于第一个问题,选择是您是否允许箭头的RHS上的块或表达式。

In practice, I find that shorter case bodies are usually preferable, so I can certainly imagine your alternative syntax resulting in crisper code. 在实践中,我发现通常更喜欢较短的盒体,所以我当然可以想象你的替代语法会产生更清晰的代码。

Consider one-line methods. 考虑一行方法。 You write: 你写:

def f(x: Int) = 2 * x

then you need to add a statement. 那么你需要添加一个声明。 I don't know if the IDE is able to auto-add parens. 我不知道IDE是否能够自动添加parens。

def f(x: Int) = { val res = 2*x ; res }

That seems no worse than requiring the same syntax for case bodies. 这似乎并不比要求案例主体使用相同的语法更糟糕。

To review, a case clause is case Pattern Guard => body . 要查看,案例子句是case Pattern Guard => body

Currently, body is a block, or a sequence of statements and a result expression. 目前, body是一个块,或一系列语句和一个结果表达式。

If body were an expression, you'd need braces for multiple statements, like a function. 如果body是一个表达式,那么你需要多个语句的大括号,比如函数。

I don't think => results in ambiguities since function literals don't qualify as patterns, unlike literals like 1 or "foo" . 我不认为=>导致歧义,因为函数文字不符合模式,不像1"foo"这样的文字。

One snag might be: { case foo => ??? } 一个障碍可能是: { case foo => ??? } { case foo => ??? } is a "pattern matching anonymous function" (SLS 8.5). { case foo => ??? }是“模式匹配匿名函数”(SLS 8.5)。 Obviously, if the case is optional or eliminated, then { foo => ??? } 显然,如果案例是可选的或被删除,那么{ foo => ??? } { foo => ??? } is ambiguous. { foo => ??? }是模糊的。 You'd have to distinguish case clauses for anon funs (where case is required) and case clauses in a match . 你必须来区分匿名玩意儿情况的条款(其中case是必需的)和条款的情况下在match

One counter-argument for the current syntax is that, in an intuition deriving from C, you always secretly hope that your match will compile to a switch table. 当前语法的一个反驳论点是,在源自C的直觉中,你总是暗地希望你的匹配将编译到切换表。 In that metaphor, the cases are labels to jump to, and a label is just the address of a sequence of statements. 在那个比喻中,案例是跳转到的标签,标签只是一系列语句的地址。

The alternative syntax might encourage a more inlined approach: 替代语法可能会鼓励更内联的方法:

x match {
  C => c(x)
  D => d(x)
  _ => ???
}
@inline def c(x: X) = ???
//etc

In this form, it looks more like a dispatch table, and the match body recalls the Map syntax, Map(a -> 1, b -> 2) , that is, a tidy simplification of the association. 在这种形式中,它看起来更像是一个调度表,并且匹配体回忆Map语法Map(a -> 1, b -> 2) ,即整理关联的简化。

One of the key aspects of code readability is the words that grab your attention. 代码可读性的一个关键方面是引起你注意的词。 For example, return grabs your attention when you see it because you know that it is such a decisive action (breaking out of the function and possible sending a value back to the caller). 例如,当你看到它时, return引起你的注意,因为你知道它是一个如此决定性的动作(打破了函数并可能将值发送回调用者)。

Another example is break --not that I like break , but it gets your attention. 另一个例子是break不是我喜欢break ,但它引起了你的注意。

I would agree with @Mik378 that case in Scala is more readable than the alternatives. 我同意@ Mik378,Scala中的case比其他case更具可读性。 Besides the compiler confusion he mentions, it gets your attention. 除了他提到的编译混淆之外,它引起了你的注意。

I am all for concise code, but there is a line between concise and illegible. 我全都是为了简洁的代码,但简洁和难以辨认之间有一条界限。 I will gladly make the trade of 4n characters (where n is the number of cases) for the substantial readability that I get in return. 我很乐意进行4n个字符的交易(其中n是个案数量),以获得我得到的实质性可读性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM