2015-04-27 75 views
0

斯卡拉新手和試圖獲得類系統的掛鉤。這裏有一個簡單的設置:正確使用斯卡拉特徵和類型

sealed trait Shape{ 
    def sides:Int 
} 

final case class Square() extends Shape { 
    def sides() = 4 
} 

final case class Triangle() extends Shape { 
    def sides() = 3 
} 

現在,我想創建一個函數,它shape類型的東西,我們知道會有一個sides()方法來實現,並使用該方法的。

def someFunction(a: Shape)={ 
    val aShape = a() 
    aShape.sides() 
} 

但是這擊中了錯誤的val aShape = a(),因爲沒有類型a

我意識到在這個例子中,創建someFunction是過度的,因爲可以直接從對象訪問sides()。但我的主要問題是在someFunction的上下文中 - 我想將一個類傳遞給一個函數,並實例化該類的一個對象,然後對該對象執行一些操作。謝謝你的幫助。

+1

刪除'a()'的parens,它是一個值,而不是函數,方法,構造函數,.. –

回答

0

除非shape具有apply函數,否則不能在shape對象上調用()

如果你想分配aShapea,只需寫val aShape = a

但因爲我沒有看到附加價值,你不妨致電sides功能直接a

def someFunction(a:shape) = { 
    val sides = a.sides 
    // use sides 
} 
1

什麼是你想與該行的代碼,這樣做?你已經有一個shape,傳入的那個叫a。只要刪除該行,並致電a.sides()

在風格上,有幾個問題。首先,班級名稱應以大寫字母開頭。其次,sides看起來像一個不可變的屬性,而不是一個變異的方法,所以它應該被聲明並覆蓋而不用括號。您的子類中還需要override修飾符。最後,你可以不用空括號:{4}應該只是4

0

這是最接近翻譯爲你寫的:

sealed trait Shape { 
    def sides: Int 
} 

case object Square extends Shape { 
    override val sides = 4 
} 

case object Triangle extends Shape { 
    override val sides = 3 
} 

def someFunction(a: Shape) = 
    val shapeSides = a.sides 

一些注意事項:在斯卡拉

  • 類應該駝峯
  • 你的子類沒有實例成員,所以你可以使用單身物件
  • 如果您有a: Shape這意味着aShape,而且您有沒有定義任何可以讓你致電()的東西。
  • 時裏面有
  • 只有一個表達式可以覆蓋一個defval,如果它是靜態
+0

感謝您的幫助。我意識到在這個例子中,創建'someFunction'是過度的,因爲'sides()'可以直接從對象中訪問。但我的主要問題是在'someFunction'的上下文中 - 我想傳遞一個類到該函數,並實例化該類的一個對象,然後對該對象執行一些操作。我會澄清這個問題。 – keegan

+0

你通常不會傳入一個類,然後創建一個實例,你傳入一個實例。你想創建一個基於邊數輸入的實例嗎?你試圖解決什麼是真正的問題? – Daenyth

+0

謝謝,我正在考慮通過這個錯誤,這有助於澄清我的理解。我會試着想出一個我的實際問題的緊湊版本。 – keegan

1

有幾種方法可以做到這一點,你可以省略括號。其中一個是使用reflection的複雜類型,第二個稍微簡單一點,使用builder,第三個對於您的用例最直接。 只要改變的someFunction定義

def someFunction(a:()=>Shape)={ 
    val aShape = a() 
    aShape.sides 
} 

所以someFunction(Square)返回4someFunction(Triangle)回報3。請注意,此工作只有case class ES,因爲真實的東西,我們是路過這裏就不類本身,但它是自動生成的companion object

但更多的時候也沒有必要定義類,你可以除了頂層的事情任何上下文中寫就像

def square() = new Shape{ 
    def sides() = 4 
} 

def triangle() = new Shape{ 
    def sides() = 3 
} 

接下來的事情:與空參數列表方法一般讀爲方法有副作用。因此,它是更方便地定義諸如

sealed trait Shape{ 
    def sides:Int 
} 

你的類型,如果你這樣定義

def square = new Shape{ 
    def sides = 4 
} 

def triangle = new Shape{ 
    def sides = 3 
} 

你的建設者,你應該把它們作爲someFunction(square _)講,你會使用的方法調用,而不是價值它的返回

最後一件事是:如果您確實需要代碼,它會創建一些對象,但它可能包含複雜的計算,資源處理或一些可能的異常,所以您想要保留它的執行直到它真的需要,喲你可以使用call-by-name parameters這相當於R,我假設你熟悉