英文原文:http://docs.scala-lang.org/style/
譯文如下:
一、接口
在可能的情況下使用類型推斷,但首先要清楚,并且在公共API中有利于明确。
您幾乎不應該注釋私有字段或本地變量的類型,因為它們的類型通常會立即顯示在其值中:
private val name = "Daniel"
但是,您可能希望仍然顯示配置設定值具有複雜或非顯而易見形式的類型。
所有公共方法都應該有明确的類型注釋。在這些情況下,類型推斷可能會破壞封裝,因為它取決于内部方法和類詳細資訊。沒有明确的類型,對方法或值的内部結構的更改可能會改變類的公共API而不發出警告,進而潛在地破壞用戶端代碼。顯式類型注釋也有助于提高編譯時間。
函數值
函數值支援類型推斷的特殊情況,值得自行調用:
val ls: List[String] = ...
ls map (str => str.toInt)
在Scala已經知道我們聲明的函數值的類型的情況下,不需要注釋參數(在這種情況下
str
)。這是一個非常有幫助的推論,應該盡可能優先。請注意,對函數值進行操作的隐式轉換将使該推斷無效,強制顯式注釋參數類型。
二、注釋
類型注釋應根據以下模闆進行圖案化:
value: Type
這是Scala大多數标準庫和Martin Odersky所有例子所采用的風格。值和類型之間的空間有助于準确解析文法。将冒号放置在值的末尾而不是類型的開始的原因是為了避免在這種情況下的混淆:
value :::
這實際上是有效的Scala,聲明一個值為類型
::
。顯然,字首風格的注解冒号大大地混亂了事情。
三、歸屬
類型歸屬通常與類型注釋混淆,因為Scala中的文法相同。以下是歸屬的例子:
Nil: List[String]
Set(values: _*)
"Daniel": AnyRef
解決方案基本上隻是在編譯時為了類型檢查器而進行的更新。它的使用并不常見,但它有時會發生。最常見的歸因情況是使用單個
Seq
參數調用varargs方法。這是通過歸納
_*
類型來完成的(如上面的第二個例子)。
Ascription遵循類型注釋約定; 冒号後面有一個空格。
四、函數
應該使用參數類型,箭頭和傳回類型之間的空格聲明函數類型:
def foo(f: Int => String) = ...
def
bar
(
f
:
(
Boolean
,
Double
)
=>
List
[
String
])
=
...應盡可能省略括号(例如,arity-1的方法,如
Int => String
)。
元數-1
Scala具有用于聲明arity-1功能的類型的特殊文法。例如:
def map[B](f: A => B) = ...
具體來說,括号可以從參數類型中省略。是以,我們并沒有聲明
f
是類型的
(A) => B
,因為這将是不必要的冗長。考慮更極端的例子:
// wrong!
def foo(f: (Int) => (String) => (Boolean) => Double) = ...
// right! def
foo
(
f
:
Int
=>
String
=>
Boolean
=>
Double
)
=
...
通過省略括号,我們儲存了六個全部字元,并大大提高了類型表達式的可讀性。
五、結構類型
如果結構類型的長度小于50個字元,則應在單行上聲明。否則,它們應該分割成多行,(通常)配置設定給自己的類型别名:
// wrong!
def foo(a: { def bar(a: Int, b: Int): String; val baz: List[String => String] }) = ...
// right! private
type
FooParam
=
{ val baz
:
List
[
String
=>
String
]
def
bar
(
a
:
Int
,
b
:
Int
):
String }
def
foo
(
a
:
FooParam
)
=
...
更簡單的結構類型(不超過50個字元)可以被聲明和使用内聯:
def foo(a: { val bar: String }) = ...
在内部聲明結構類型時,每個成員應該用分号和單個空格分開,開放大括号後面應該有 一個空格,而關閉大括号應該在前面加上一個空格(如上面兩個例子所示)。
結構類型在運作時通過反射來實作,并且本質上比标稱類型的性能更差。開發商應優先使用名義類型,除非結構類型提供明确的收益。