風格指南

控制結構

語言

所有控制結構都應該在定義關鍵字後加上一個空格

// right!
if (foo) bar else baz
for (i <- 0 to 10) { ... }
while (true) { println("Hello, World!") }

// wrong!
if(foo) bar else baz
for(i <- 0 to 10) { ... }
while(true) { println("Hello, World!") }

大括號

當控制結構表示純函式運算,且控制結構的所有分支(與 if/else 相關)都是單行表達式時,應省略大括號。請記住以下準則

  • if - 如果您有 else 子句,請省略大括號。否則,即使內容只有一行,也要用大括號將內容括起來。
  • while - 永遠不要省略大括號(while 無法以純函數的方式使用)。
  • for - 如果您有 yield 子句,請省略大括號。否則,請用大括號括住內容,即使內容只有一行。
  • case - 在 case 子句中永遠省略大括號。
val news = if (foo)
  goodNews()
else
  badNews()

if (foo) {
  println("foo was true")
}

news match {
  case "good" => println("Good news!")
  case "bad" => println("Bad news!")
}

理解

Scala 有能力以多個產生器(通常多於一個 <- 符號)表示 for 理解。在這種情況下,可以使用兩種替代語法

// wrong!
for (x <- board.rows; y <- board.files)
  yield (x, y)

// right!
for {
  x <- board.rows
  y <- board.files
} yield (x, y)

雖然後面的樣式較為冗長,但通常被認為較容易閱讀且更具「可擴充性」(表示理解的複雜性增加時不會變得模糊不清)。對於所有多於一個產生器的 for 理解,您都應該優先使用此形式。僅有一個產生器的理解(例如 for (i <- 0 to 10) yield i)應使用第一個形式(小括號而非大括號)。

此規則的例外情況是缺少 yield 子句的 for 理解。在這種情況下,該結構實際上是一個迴圈,而不是一個函數理解,並且將產生器串接在小括號中通常比使用語法混淆的 } { 結構更具可讀性

// wrong!
for {
  x <- board.rows
  y <- board.files
} {
  printf("(%d, %d)", x, y)
}

// right!
for (x <- board.rows; y <- board.files) {
  printf("(%d, %d)", x, y)
}

最後,for 理解優先於對 mapflatMapfilter 的鏈式呼叫,因為這可能會難以閱讀(這是增強 for 理解的目的之一)。

瑣碎條件

在某些情況下,建立一個簡短的 if/else 表達式,以便在較大的表達式中嵌套使用,會很有用。在 Java 中,這種情況通常會由三元運算子 (?/:) 來處理,這是一個 Scala 所缺乏的語法裝置。在這些情況下(以及任何時候你有一個極簡短的 if/else 表達式),將「then」和「else」分支放在與 ifelse 關鍵字相同的行上是允許的

val res = if (foo) bar else baz

這裡的重點是,將兩個分支與 if/else 內聯不會妨礙可讀性。請注意,這種樣式絕不應與命令式的 if 表達式一起使用,也不應使用大括號。

此頁面的貢獻者