2013-06-20 2 views
4

Вот Scala кодОпуская скобки

#1 
def method1 = { 
    map1.foreach({ 
    case(key, value) => { println("key " + key + " value " + value) } 
    }) 
} 

#2 
def method1 = { 
    map1.foreach{ 
    case(key, value) => { println("key " + key + " value " + value) } 
    } 
} 

Это почти цифры для меня, но тем не менее я хочу, чтобы сделать его более ясным: почему можно опустить скобки в этом случае?

+1

Вы можете еще больше удалить некоторые фигурные скобки: определение функции method1 = map1 .foreach {case (key, value) => println ("key" + key + "value" + value)} ' –

ответ

4

Вы можете всегда использовать круг аргументов аргументов для фигурных скобок в Scala. Например

def test(i: Int) {} 

test { 3 } 

Основой для этого является определение аргументов выражений, покрытый раздел §6.6 из Scala Language Specification (SLS):

ArgumentExprs ::= ‘(’ [Exprs] ‘)’ 
       | ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ’)’ 
       | [nl] BlockExpr 

Фигурные скобки покрываются последнем случае (блок экспрессии), который по существу равен ‘{’ Block ‘}’ (см. начало главы 6 SLS).

Это не идет для условных выражений, if, (§6.16 СЛС) и while выражений цикла (§6.17 СЛС), но это работает для for постижений (§6.19 СЛС), несколько несостоятельности.

Сводка соответствия шаблону или шаблон, соответствующий анонимным функциям, буквально с другой стороны должен быть определен с фигурными фигурными скобками, например. { case i: Int => i + i }, круглые скобки здесь не допускаются (§8.5 SLS).

В вашем вызове метода, foreach принимает аргумент функции, так что вы можете отбросить лишние скобки или двойные фигурные скобки:

List(1, 2).foreach({ case i => println(i) }) 
List(1, 2).foreach {{ case i => println(i) }} 

List(1, 2).foreach { case i => println(i) } // no reason to have double braces 

В этом случае сопоставление с образцом не реально купить вам что-нибудь, и вы можно использовать обычную функцию (без сопоставления с образцом), и, таким образом, следующий будет работать, тоже:

List(1, 2).foreach(i => println(i)) // §6.23 SLS - anonymous functions 
List(1, 2).foreach(println)   // §6.26.2/§6.26.5 - eta expansion 

в вашем случае, хотя, map метод Map «s проходит кортеж ключ и значение для фу nction, поэтому вы используете сопоставление с образцом (case) для деконструкции этого кортежа, поэтому вы должны иметь фигурные скобки. Это лучше, чем писать

map1.foreach(tup => println("key " + tup._1 + " value " + tup._2) 

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

case(key, value) => { println("key " + key + " value " + value) } 

вы должны написать

case (key, value) => println("key " + key + " value " + value) 

Существует немного полемического in this blog post относительно различных вариантов использования фигурных скобок, точек и скобок в Scala (раздел «Что не нравится «). В конце концов, вы должны решить, какой стиль лучше - это то, где люди, выступающие за «упрямые» и «не упрямые» языки, сражаются друг с другом.

В общем, вам нужны фигурные скобки, когда выражение охватывает несколько строк или если у вас есть соответствие шаблону. При вызове метода с несколькими списками параметров, часто последний список содержит один аргумент функции, так что вы получите хороший взгляд, субъективное суждение, конечно-синтаксисом:

val l = List(1, 2, 3) 
l.foldLeft(0) { 
    (sum, i) => sum + i 
} 
+0

Я думаю, вопрос в том, почему это работает:' List (1) .map {_ + 1} ' , но 'List (1) .map f' и' List (1) .map (case i => i) '- not. – senia

+0

@senia Первый случай покрывается выражением аргумента, являющимся заявлением блока. Второй случай недействителен, потому что вы пытаетесь выполнить «наполовину» вызов оператора инфикса (см. Снова главу 6 SLS). Инфиксное выражение - 'InfixExpr id [nl] InfixExpr', поэтому здесь не может быть периода. «Список (1) map f' является действительным вызовом инфикса. –

+0

Если фигурные скобки являются частью функции буквальнее, чем в первом случае, а второй случай равен. Если скобки заменяют скобки, то первый случай и третий случай равны. Так что это? На самом деле в этом случае скобки являются заменой для скобок **, а ** функциональный литерал синтаксический анализ не является независимым от контекста. Поэтому '{case i => i}' равно '{f}' (while '(case i => i)' не равно '(f)'). Но я не могу найти соответствующую документацию. – senia

Смежные вопросы