Scala: Можете ли вы использовать "foo match {bar}" в выражении без скобок? - PullRequest
9 голосов
/ 23 сентября 2011

Зачем здесь скобки? Есть ли какие-то правила приоритета, которые я должен знать?

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

Спасибо! * * 1004

Ответы [ 3 ]

8 голосов
/ 23 сентября 2011

Как говорит Agilesteel, совпадение не рассматривается как простое выражение и не является оператором if, поэтому необходимо заключить это выражение в скобки. От Язык Скала Спецификация , 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}
    | ‘:’ ‘_’ ‘*’
5 голосов
/ 23 сентября 2011

После некоторой проверки в спецификации Scala, я думаю, что могу попробовать.Если я ошибаюсь, пожалуйста, исправьте меня.

сначала if или match определяются как Expr - выражения.

Вы пытаетесь создать инфиксное выражение (определяется какиспользование оператора между двумя выражениями)

Однако спецификация (раздел 3.2.8) гласит, что:

Все операторы типа in имеют одинаковый приоритет;Для группировки необходимо использовать круглые скобки

Также указывается, что:

В последовательности последовательного типа в операциях с фиксированным числом t0 op1 t1 op2.,.opn tn, все операторы op1,.,,, opn должен иметь одинаковую ассоциативность.Если все они левоассоциативны, последовательность интерпретируется как (... (T0 op1 t1) op2..) Opn tn.

Поэтому я считаю, что Scala не знает, чтосначала уменьшите: совпадение или вызов метода «+».

Взгляните на этот ответ

Пожалуйста, исправьте меня, если я ошибаюсь.

3 голосов
/ 23 сентября 2011

Соответствующее выражение не считается простым выражением.Вот аналогичный пример:

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

Очевидно, вы не можете писать сложные выражения, где хотите.Я не знаю почему и надеюсь, что кто-то с большим знанием темы даст вам лучший ответ.

...