http://docs.scala-lang.org/overviews/core/value-classes.html html
class Wrapper(val underlying: Int) extends AnyVal
這個類有一個單一的、公共的val參數,它是底層的運行時表示(underlying runtime representation)。編譯的時候,它是Wrapper類型的,而運行時,它表示一個Int。一個值類能夠定義方法(defs),但不能定義屬性(vals、vars),也不能嵌套特質(traits)、類或對象: java
class Wrapper(val underlying: Int) extends AnyVal { def foo: Wrapper = new Wrapper(underlying * 19) }一個值類只能擴展普通特質,但自身不能被擴展(值類是final型的)。普通特質是指那些擴展自Any(trait XXX extends Any)、只有方法和成員變量、沒有初始化的特質。對於值類而言,普通特質容許基本的方法繼承,但他們會產生資源分配開銷。例如:
trait Printable extends Any { def print(): Unit = println(this) } class Wrapper(val underlying: Int) extends AnyVal with Printable val w = new Wrapper(3) w.print() // 實際上須要實例化一個Wrapper對象
這個文檔的剩餘部分展現了一些用法示例,詳細說明什麼時候會進行資源分配,而什麼時候不會發生,而且用具體的例子說明值類的侷限。 編程
class RichInt(val self: Int) extends AnyVal { def toHexString: String = java.lang.Integer.toHexString(self) }
在運行時,表達式3.toHexString會優化成至關於對靜態對象的方法調用(RichInt$.MODULE$.extension$toHexString(3)),而不是對新實例化的對象的方法調用。 數組
class Meter(val value: Double) extends AnyVal { def +(m: Meter): Meter = new Meter(value + m.value) }
兩個距離增長的代碼就像這樣: 安全
val x = new Meter(3.4) val y = new Meter(4.3) val z = x + y
運行時,並無真的建立兩個Meter的實例,而是用原生的double類型。 注意:在實踐中,你可使用case class和/或擴展方法來得到更簡潔的語法。 app
因爲JVM不支持值類,Scala有時候須要實例化值類。具體細節請查看SIP-15。 ide
三、運行時類型檢查,好比模式匹配(pattern matching)。 函數
trait Distance extends Any case class Meter(val value: Double) extends AnyVal with Distance若是一個方法接受Distance類型的值,那麼它須要一個真正的Meter實例。在接下來的例子中,Meter類會被實例化。
def add(a: Distance, b: Distance): Distance = ... add(Meter(3.4), Meter(4.3))若是add方法簽名用下面的代替:
def add(a: Meter, b: Meter): Meter = ...那麼資源分配就不是必需的。這個規則的另外一個實例是,當值類被用做類型參數。例如,調用identity時,必需建立Meter的實例:
def identity[T](t: T): T = t identity(Meter(5.0))另外一個資源分配的狀況是指定一個數組,即便它是這個值類的數組。例如:
val m = Meter(5.0) val array = Array[Meter](m)這個數組包含實際的Meter實例,而非原生類型double。
case class P(val i: Int) extends AnyVal val p = new P(3) p match { // new P instantiated here case P(3) => println("Matched 3") case P(x) => println("Not 3") }
目前值類有幾個侷限,很大程度上是由於JVM沒有原生支持值類的概念。值類的實現詳情和它們的侷限性,請看SIP-15。 工具
七、不能擴展另外一個類。 優化
這節提供了不少關於這些缺陷的具體影響,它們在「必要的資源分配」節沒有描述。
不容許多個構造器參數:class Complex(val real: Double, val imag: Double) extends AnyValScala編譯器會生成以下的錯誤消息:
Complex.scala:1: error: value class needs to have exactly one public val parameter class Complex(val real: Double, val imag: Double) extends AnyVal ^因爲構造器參數必須是val,因此不能是傳名參數(by-name parameter,Scala編程一書中翻譯爲傳名參數):
NoByName.scala:1: error: `val' parameters may not be call-by-name class NoByName(val x: => Int) extends AnyVal ^
Scala不容許延遲初始化的構造器參數,因此值類也不支持。也不容許多構造器。
(按個人理解,一個無參函數字面量()=>Int,去掉()就是傳名函數,因而就能夠用「1+2」做爲入參,來代替「()=>{1+2}」這種噁心的寫法)
class Secondary(val x: Int) extends AnyVal { def this(y: Double) = this(y.toInt) } Secondary.scala:2: error: value class may not have secondary constructors def this(y: Double) = this(y.toInt) ^值類不能有lazy val或val的成員,也不能有嵌套類,特質,或對象。
class NoLazyMember(val evaluate: () => Double) extends AnyVal { val member: Int = 3 lazy val x: Double = evaluate() object NestedObject class NestedClass } Invalid.scala:2: error: this statement is not allowed in value class: private[this] val member: Int = 3 val member: Int = 3 ^ Invalid.scala:3: error: this statement is not allowed in value class: lazy private[this] var x: Double = NoLazyMember.this.evaluate.apply() lazy val x: Double = evaluate() ^ Invalid.scala:4: error: value class may not have nested module definitions object NestedObject ^ Invalid.scala:5: error: value class may not have nested class definitions class NestedClass ^注意本地類,特質和對象也是不容許的:
class NoLocalTemplates(val x: Int) extends AnyVal { def aMethod = { class Local ... } }當前的實現約束是,值類不能被嵌套:
class Outer(val inner: Inner) extends AnyVal class Inner(val value: Int) extends AnyVal Nested.scala:1: error: value class may not wrap another user-defined value class class Outer(val inner: Inner) extends AnyVal ^此外,不能在結構類型(structural types)的方法參數或返回類型中使用值類:
class Value(val x: Int) extends AnyVal object Usage { def anyValue(v: { def value: Value }): Value = v.value } Struct.scala:3: error: Result type in structural refinement may not refer to a user-defined value class def anyValue(v: { def value: Value }): Value = ^值類不能擴展非普通特質(non-universal trait),值類也不能被擴展:
trait NotUniversal class Value(val x: Int) extends AnyVal with notUniversal class Extend(x: Int) extends Value(x) Extend.scala:2: error: illegal inheritance; superclass AnyVal is not a subclass of the superclass Object of the mixin trait NotUniversal class Value(val x: Int) extends AnyVal with NotUniversal ^ Extend.scala:3: error: illegal inheritance from final class Value class Extend(x: Int) extends Value(x) ^第二個錯誤信息代表,儘管值類沒有顯示聲明final修飾符,但它是假定存在的。
class Outer { class Inner(val x: Int) extends AnyVal } Outer.scala:2: error: value class may not be a member of another class class Inner(val x: Int) extends AnyVal ^可是下面的例子是容許的,由於它被頂級對象包圍:
object Outer { class Inner(val x: Int) extends AnyVal }
(好了,就到這吧)
2013-1-8 到家8點多了,寫了一下子年會節目的段子,而後想找幾個輔助翻譯的工具,都不太給力,仍是用網頁翻譯和詞典吧。快11點了,該睡覺了,才翻譯完《簡介》部分,要是按這個速度,估計我看完一本英文原版書的話得須要一年,呵呵。 2013-1-9 上六天班了,還有兩天,堅持堅持。今天整了一小段《擴展方法》,翻譯這活真累,之後就一小段一小段翻譯吧。 2013-1-24 中間隔了好長時間,中間有一週晚上到家就玩遊戲,而後又去看sbt。今天趁公司沒事,偷摸把剩下的弄完。剩下的那些好長啊,還有好多看不懂的,哎。