Scala:你可以使用“foo match { bar }”吗?在没有括号的表达式中?

发布于 2024-12-06 02:09:48 字数 307 浏览 0 评论 0原文

这里为什么需要括号?我应该知道一些优先规则吗?

scala> 'x' match { case _ => 1 } + 1
<console>:1: error: ';' expected but identifier found.
       'x' match { case _ => 1 } + 1
                                 ^

scala> ('x' match { case _ => 1 }) + 1
res2: Int = 2

谢谢!

Why are the parentheses needed here? Are there some precedence rules I should know?

scala> 'x' match { case _ => 1 } + 1
<console>:1: error: ';' expected but identifier found.
       'x' match { case _ => 1 } + 1
                                 ^

scala> ('x' match { case _ => 1 }) + 1
res2: Int = 2

Thanks!

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

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

发布评论

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

评论(3

天暗了我发光 2024-12-13 02:09:48

正如 Agilesteel 所说,匹配不被视为简单的表达式,if 语句也不被视为简单的表达式,因此您需要用括号将表达式括起来。来自 Scala 语言
规范
,6 表达式,p73,匹配是一个 Expr,就像一个 if 一样。 + 运算符两侧仅接受 SimpleExpr。

要将 Expr 转换为 SimpleExpr,必须用 () 将其括起来。

为了完整性而复制:

Expr ::= (Bindings | id | ‘_’) ‘=>’ Expr
    | Expr1
Expr1 ::= ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] else Expr]
    | ‘while’ ‘(’ Expr ‘)’ {nl} Expr
    | ‘try’ ‘{’ Block ‘}’ [‘catch’ ‘{’ CaseClauses ‘}’] [‘finally’ Expr]
    | ‘do’ Expr [semi] ‘while’ ‘(’ Expr ’)’
    | ‘for’ (‘(’ Enumerators ‘)’ | ‘{’ Enumerators ‘}’) {nl} [‘yield’] Expr
    | ‘throw’ Expr
    | ‘return’ [Expr]
    | [SimpleExpr ‘.’] id ‘=’ Expr
    | SimpleExpr1 ArgumentExprs ‘=’ Expr
    | PostfixExpr
    | PostfixExpr Ascription
    | PostfixExpr ‘match’ ‘{’ CaseClauses ‘}’
PostfixExpr ::= InfixExpr [id [nl]]
InfixExpr ::= PrefixExpr
    | InfixExpr id [nl] InfixExpr
PrefixExpr ::= [‘-’ | ‘+’ | ‘~’ | ‘!’] SimpleExpr
SimpleExpr ::= ‘new’ (ClassTemplate | TemplateBody)
    | BlockExpr
    | SimpleExpr1 [‘_’]
SimpleExpr1 ::= Literal
    | Path
    | ‘_’
    | ‘(’ [Exprs] ‘)’
    | SimpleExpr ‘.’ id s
    | SimpleExpr TypeArgs
    | SimpleExpr1 ArgumentExprs
    | XmlExpr
Exprs ::= Expr {‘,’ Expr}
BlockExpr ::= ‘{’ CaseClauses ‘}’
    | ‘{’ Block ‘}’
Block ::= {BlockStat semi} [ResultExpr]
ResultExpr ::= Expr1
    | (Bindings | ([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block
Ascription ::= ‘:’ InfixType
    | ‘:’ Annotation {Annotation}
    | ‘:’ ‘_’ ‘*’

As Agilesteel says, a match is not considered as a simple expression, nor is an if statement, so you need to surround the expression with parentheses. From The Scala Language
Specification
, 6 Expressions, p73, the match is an Expr, as is an if. Only SimpleExpr are accepted either side of the + operator.

To convert an Expr into a SimpleExpr, you have to surround it with ().

Copied for completeness:

Expr ::= (Bindings | id | ‘_’) ‘=>’ Expr
    | Expr1
Expr1 ::= ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] else Expr]
    | ‘while’ ‘(’ Expr ‘)’ {nl} Expr
    | ‘try’ ‘{’ Block ‘}’ [‘catch’ ‘{’ CaseClauses ‘}’] [‘finally’ Expr]
    | ‘do’ Expr [semi] ‘while’ ‘(’ Expr ’)’
    | ‘for’ (‘(’ Enumerators ‘)’ | ‘{’ Enumerators ‘}’) {nl} [‘yield’] Expr
    | ‘throw’ Expr
    | ‘return’ [Expr]
    | [SimpleExpr ‘.’] id ‘=’ Expr
    | SimpleExpr1 ArgumentExprs ‘=’ Expr
    | PostfixExpr
    | PostfixExpr Ascription
    | PostfixExpr ‘match’ ‘{’ CaseClauses ‘}’
PostfixExpr ::= InfixExpr [id [nl]]
InfixExpr ::= PrefixExpr
    | InfixExpr id [nl] InfixExpr
PrefixExpr ::= [‘-’ | ‘+’ | ‘~’ | ‘!’] SimpleExpr
SimpleExpr ::= ‘new’ (ClassTemplate | TemplateBody)
    | BlockExpr
    | SimpleExpr1 [‘_’]
SimpleExpr1 ::= Literal
    | Path
    | ‘_’
    | ‘(’ [Exprs] ‘)’
    | SimpleExpr ‘.’ id s
    | SimpleExpr TypeArgs
    | SimpleExpr1 ArgumentExprs
    | XmlExpr
Exprs ::= Expr {‘,’ Expr}
BlockExpr ::= ‘{’ CaseClauses ‘}’
    | ‘{’ Block ‘}’
Block ::= {BlockStat semi} [ResultExpr]
ResultExpr ::= Expr1
    | (Bindings | ([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block
Ascription ::= ‘:’ InfixType
    | ‘:’ Annotation {Annotation}
    | ‘:’ ‘_’ ‘*’
記憶穿過時間隧道 2024-12-13 02:09:48

经过对 Scala 规范的一些检查后,我想我可以尝试一下。
如果我错了请纠正我。

首先,ifmatch 被定义为 Expr - 表达式。

您正在尝试创建一个中缀表达式(通过在两个表达式之间使用运算符来定义)

但是 规范(第 3.2.8 节)指出:

所有类型中缀运算符具有相同的优先级;括号必须
用于分组

它还指出:

在连续类型中缀操作序列中 t0 op1 t1 op2 。 。
.opn tn,所有运算符 op1, . 。 。 , opn 必须具有相同的
关联性。如果它们都是左关联的,则顺序为
解释为 (...(t0 op1 t1) op2...) opn tn。

所以我的看法是 Scala 不知道首先要减少什么:匹配或方法“+”调用。

看看这个答案

如果我是的话请纠正我错误的。

After some inspection in the Scala specification, I think I can give it a shot.
If I am wrong please correct me.

first, an if or match are defined as Expr - expressions.

You are trying to create an infix expression (defined by the use of the operator between two expressions)

However the especification (section 3.2.8) states that :

All type infix operators have the same precedence; parentheses have to
be used for grouping

It also also states that:

In a sequence of consecutive type infix operations t0 op1 t1 op2 . .
.opn tn, all operators op1, . . . , opn must have the same
associativity. If they are all left-associative, the sequence is
interpreted as (. . . (t0 op1 t1) op2 . . .) opn tn.

So my take is that Scala does not know what to reduce first: the match or the method '+' invocation.

Take a look at this answer

Please correct me if I am wrong.

寂寞美少年 2024-12-13 02:09:48

匹配表达式不被视为简单表达式。这是一个类似的例子:

scala> val foo = "bar" + if(3 < 5) 3 else 5   // does not compile
scala> val foo = "bar" + (if(3 < 5) 3 else 5) // does compile

显然你不能在任何你想要的地方编写复杂的表达式。我不知道为什么,希望对此主题有更多了解的人能给您更好的答案。

A match expression is not considered as simple expression. Here is a similar example:

scala> val foo = "bar" + if(3 < 5) 3 else 5   // does not compile
scala> val foo = "bar" + (if(3 < 5) 3 else 5) // does compile

Apparently you can't write complex expressions wherever you want. I don't know why and hope that someone with more knowledge of the topic will give you a better answer.

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