2011-10-02 41 views
4

據我瞭解,斯卡拉如果我創建使用new關鍵字類,並按照類名稱與一個構造函數創建一個匿名類:Scala:我可以用工廠方法重現匿名類的創建嗎?

class MyClass { 
    def doStuff() { 
    // ... 
    } 
} 

val mc = new MyClass { 
    doStuff() 
} 

的好處是,在構造函數中的所有代碼屬於新對象的範圍。

有沒有一種方法可以重現此類語法,其中類是由工廠方法創建的而不是new關鍵字?即使下面的代碼工作:

val mf = new MyFactory 

val mc = mf.MyClass { 
    doStuff() 
} 

我找不到辦法做到這一點,但斯卡拉有這麼多,它可能很容易!

使用的import通過@Ricky的建議之下,我可以得到:

val mf = MyFactory; 
val mc = mf.MyClass 

{ 
    import mc._ 
    doStuff() 
} 

(在需要的塊前的空行),但代碼塊不是構造函數。

+1

你只是希望能夠添加語句(在你的例子一樣'doStuff()')來運行或整個場definit離子?前者很容易通過傳遞一個call-by-need塊,後者聽起來非常棘手...... – Owen

+0

我希望能夠在正在創建的對象範圍內自動添加代碼,無論是調用方法還是訪問字段。 –

回答

1

我不認爲這是可能的。然而,一個常見的模式是將一個參數添加到工廠方法,這需要功能修改所創建的對象:

trait MyClass { 
    var name = "" 
    def doStuff():Unit 
} 

class Foo extends MyClass { 
    def doStuff() { println("FOO: " + name) } 
} 

trait MyClassFactory { 
    def make: MyClass 
    def apply(body: MyClass => Unit) = { 
    val mc = make 
    body(mc) 
    mc 
    } 
} 

object FooFactory extends MyClassFactory { 
    def make = new Foo 
} 

然後,您可以創建和修改實例與語法接近你的例子:

val foo = FooFactory { f=> 
    f.name = "Joe" 
    f.doStuff 
} 
+0

謝謝,這肯定比我設法得到的更多。 –

2

你可以這樣做,但你還是要保持new關鍵字,並創建嵌套類的路徑依賴型:

class Bippy(x: Int) { 
    class Bop { 
    def getIt = x 
    } 
} 

val bip = new Bippy(7) 
val bop = new bip.Bop 

bop.getIt // yields 7 

val bop2 = new bip.Bop{ override def getIt = 42 } 

bop2.getIt // yields 42 
+0

謝謝。我沒有使用路徑依賴類型,所以我需要考慮這個,看看它是否做我想要的。 –

+0

它允許你創建一些給定類型的匿名子類,但仍然在一些外部環境的周圍(如果你願意,可以稱它爲工廠)。 *感覺*就像它是你以後的樣子:) –

+0

這聽起來確實如此。那麼我認真學習路徑依賴類型的時間。再次感謝。 –

0

這聽起來像你只是希望混合在一起。

new T { 
    override def toString = "My implementation here." 
} 

你可以代替寫

trait MyImplementation { 
    override def toString = "My implementation here." 
} 

new Foo with MyImplementation 

但是,如果你只是希望得到成員:而不是調用myFactoryMethod(classOf [美孚]在理想情況下會做(如果斯卡拉允許的話)的無資質訪問新對象的,還記得你可以從任何穩定的標識符輸入:

val foo = new Bar 
import foo._ 
println(baz) //where baz is a member of foo. 
+0

謝謝。如果我正確地理解了你,我可以看到使用特質的問題是工廠需要知道應用什麼特質,但也許我可以告訴它? 關於你的第二點,我發現我可以用這樣的導入: VAL MF = MyFactory VAL MC = mf.MyClass { 進口mc._ doStuff() } (凡空白行之前需要塊),但該代碼塊不是一個構造函數。 –

+0

代碼在那裏有點損傷,所以我在原來的問題中加入了一些東西來解釋我在哪裏使用'import'。再次感謝。 –

+0

關於工廠瞭解應用的特點,我認爲你可以在沒有工廠的情況下完成工作,只需使用MyImplementation編寫新的Foo。在特徵中進行混合並不是可以推遲到運行時間,因爲它涉及字節碼生成,而且Scala不提供自定義類加載器。 –

相關問題