2011-09-03 72 views
19

Scala語言要求您在使用它之前初始化您的實例變量。但是,Scala不會爲您的變量提供默認值。相反,你必須使用通配符下劃線,這就像一個默認值手動設置它的值,如下爲什麼Scala語言要求您初始化實例變量而不是依賴默認值?

var name:String = _ 

我知道,我知道......我可以在類定義定義構造函數,這需要作爲參數提供實例變量,所以斯卡拉不會強迫其初始化如下圖所示

class Person(var name:String) 

但是,我需要聲明它的身體,因爲我需要使用Java註解,其的ElementType爲字段或方法;也就是說,它可以應用於在我們的類的主體中聲明的實例變量或方法。

問題:爲什麼Scala語言要求你初始化一個實例變量 - 是它,你需要有一個默認值_或任何 - 一類,而不是依靠一個默認值體中聲明?

+2

Martin的偏好是我的猜測:-)至少它是明確的,額外的2個字符(4個空格)並不是非常令人生畏的。 Java(一種非常冗長的語言)讓賦值被省略似乎很愚蠢。另外,說「構造函數參數」(不知道它們實際稱爲: - /)不是被強制初始化 - 它們當然是在對象被實例化時。 – 2011-09-03 04:45:51

回答

6

可以當你將它指定爲構造函數的參數應用註解。另外,您可能需要使用元註釋來限制您正在使用的註釋的目標 - 請參閱http://www.scala-lang.org/api/2.10.2-RC2/index.html#scala.annotation.meta.package

但是,有關「依賴默認值」的問題尚不清楚。使用下劃線進行初始化對應於將變量的值分配給null。你在想什麼其他的默認設置?

+0

我知道下劃線符號用於分配默認值。但是,我想知道爲什麼Scala不允許像var name:String(沒有下劃線賦值)之類的東西,而是在類體中聲明的時候。你指出了我不知道的Scala(+1)的一個很好的特性。然而,它不能滿足我的需求,因爲我還需要一個無參數的構造函數,如果我在類定義中聲明的構造函數中聲明瞭實例變量 –

+4

需要賦值的原因是,我相信這樣編譯器可以區分一個抽象變量(它被編譯爲一對抽象方法)和一個具體的變量,這也需要在類文件中生成該字段。 –

4

Scala在類體中的「var name:String」沒有問題。你試過了嗎?儘管如此,它並不意味着你想要它的意思。這是一個抽象變種。

abstract class A { 
    var name: String 
} 
// some possible uses for abstract vars 
trait B { type T ; var name: T } 
class B1 extends B { type T = Int ; var name: Int = 5 } 
// hey, no storage 
class B2 extends B { type T = String ; def name = "abc" ; def name_=(x: String) =() } 
+0

如果我只是聲明var name:String;當編譯成一個.class文件時,Scala編譯器會抱怨:變量名沒有定義。所以我想知道,即使由於設計問題,爲什麼Scala不允許在沒有聲明其初始值的情況下在類體中使用var name:String;無論是默認值還是其他值 –

+1

你可以重讀我的答案,你似乎已經忽略了。你在問爲什麼「抽象」存在?一個未實現的抽象成員意味着你不能實例化這個類。這是設計,就像在java中一樣。 – extempore

18

如果你使用像你在聲明下面的代碼,該代碼name應該是抽象的:

class A { 
    var name: String 
} 

我想你已經知道了。所以你的問題不是語法上的。 答案與其他可能的抽象候選一致。

假設你想要做這樣的事情:

class A { 
    var variable: String = _ // variable has some default value (probably null) 
    val value: String = _ // value cannot have any default values, since it cannot be reassigned later. 
    def method: String = _ // method could return some default value (probably null) 
    type theType = _ // what should the default type be? (Any perhaps?) 
} 

最後三個例子甚至不編譯。現在假設你想要做這樣的事情:

class A { 
    var variable: String 
    val value: String 
    def method: String 
    type theType 
} 

從我的角度來看,即使有人勉強誰瞭解斯卡拉看到只聲明。沒有辦法曲解它們,因爲除了聲明之外什麼都沒有。當你來自另一種語言並且假設有一些默認值時,唯一的混淆就產生了。但是,只要你看到第一個例子(具有默認值的例子),這種混淆就消失了。而且你的類必須是抽象層次結構的一部分才能被允許聲明抽象成員,所以即使你對這個語言還不熟悉,你已經從編譯器中獲得了一些額外的幫助。

我希望這可以回答你的問題和快樂的編碼。

+1

謝謝你的回答(+1) –

相關問題