2011-07-16 47 views

回答

9

在Scala中,你會只是做

class MyClass { 
    private var myString = "hello" 
} 

這看起來不一樣的東西,不是嗎?但是讓我們看看字節碼是什麼Java代碼實際上產生(我們稱之爲類JavaConstructor):

public JavaConstructor(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: aload_0 
    5: aconst_null 
    6: putfield #2; //Field myString:Ljava/lang/String; 
    9: aload_0 
    10: ldC#3; //String hello 
    12: putfield #2; //Field myString:Ljava/lang/String; 
    15: return 

Java已經有效地複製private String myString = null;到構造(其中null創建並存儲音符線5和6) 。因此,關於將myString設置爲null的整件事情完全是浪費;你加載它,然後立即覆蓋它。

現在,如果我們看一下相應的斯卡拉:

public ScalaConstructor(); 
    Code: 
    0: aload_0 
    1: invokespecial #18; //Method java/lang/Object."<init>":()V 
    4: aload_0 
    5: ldC#20; //String hello 
    7: putfield #10; //Field myString:Ljava/lang/String; 
    10: return 
} 

,我們看到它的一樣有效,人們希望(和反映的代碼)。

然後問題是:爲什麼你想按照你在Java中所做的方式來完成它?那麼,也許你有多個構造函數,其中一些將設置爲myString,有些則不會!將其設置爲null是一種提醒自己,在使用之前最好先初始化它的方法。

但斯卡拉不會讓你這樣做。斯卡拉真的只允許一個構造函數;其他人只是調用這個構造函數的別名。如果需要,您可以將其設置爲私有並使用大量參數進行加載,但重點是具有多個構造函數,其中一些設置了關鍵數據,而其中一些卻不是實際上是一個容易出錯的過程。最好只做一次,並寫下如

private var myString = if (someParameter) "hello" else null 

如果你真的需要這樣做。然後再次,也許你只是把它做成了var,因爲你試圖在不同的構造函數中對它進行不同的設置。只有一個構造函數,也許就沒有必要爲:

private val myString = if (someParameter) "hello" else null 

但也許現在,它的設置是否正確,我們並不真正需要的是私有的。

val myString = if (someParameter) "hello" else null 

,也許,如果經常不設置,我們應該使用,而不是一個選項:

val myString = if (someParameter) Some("hello") else None 

,然後你就會有一些看起來更像地道斯卡拉。

1

你的構造函數是默認的,它不接受任何參數。這相當於不定義構造函數並將屬性myString設置爲「hello」。既然你將它定義爲一個val,它將是不可變的(不可等同於一個java setter可用),但是你可以通過。訪問myString的值。符號(例如myClass.myString

class MyClass { 
    val myString = "hello" 
} 
相關問題