2014-01-11 43 views
0

[見下面的代碼片段] 我讀到,我有一個X是一個片斷,我有一個球員需要一塊。玩家Me試圖用Piece X來定義這件作品。然而Scala並不認爲X是一件作品,而是它看到的是'X.type'。 X.type是什麼意思?我不確定我的問題是什麼,所以我很難搜索。斯卡拉不解決X爲Y,即使X延伸Y

我不明白這可以是陰影類型[見Scala really weird Type Mismatch],因爲我沒有指定另一個'Piece',而只是指定我需要一個'Piece'。

似乎有什麼可以阻止斯卡拉解決X作爲一塊。

要嘗試在REPL

trait Piece { val piece: Char } 
case class X extends Piece { val piece: Char = 'X' } 

trait Player { val piece: Piece } 
case class Me extends Player { val piece: Piece = X } 

結果

error: type mismatch; 
found : X.type 
required: Piece 
     case class Max extends Player { val piece: Piece = X } 

回答

3

這可能是因爲X你只是描述一個類(所以它實際上是一個),而斯卡拉期待一個對象(或實例)的類型片。你會在第一種情況下這樣做,得到同樣的錯誤:

case class X extends Piece { val piece: Char = Char } 

正如你所看到的,你的版本的作品,因爲你通過一個特定的字符,而不是一個類型。如果你希望你的代碼工作,你可能要創建一個新的對象,並傳遞它:

case class Me extends Player { val piece: Piece = new X } 

編輯:作爲OP在下面的評論指出,使用X()也適用,因爲X是一類情況下它會隱式應用()方法:

case class Me extends Player { val piece: Piece = X() } 
+0

啊,非常感謝!我通常有一個參數,所以我從來沒有遇到過這個問題。即使使用X()解決了這個問題。沒有意識到一個類是一個類型。哇現在模式匹配更有意義,而類是實例藍圖的事實更加清晰,真棒。它只是點擊! – Miles

+0

這個答案實際上並不完全正確。你能否更新它以符合我的回答?只是爲了你的利益,你知道,樂於助人。 –

0

要指定類型X給變量piece,而不是X一個實例。

1

當您編寫case class X時,您還正在創建一個伴侶object X,該成員有一個成員apply,可讓您說X()。所有這些在與Scala的一些經驗後都是顯而易見的。

X.type是對象X的單例類型。它與「分配類型」無關,正如其他答案所說的那樣。

當你說X作爲一個值,它意味着對象。這是一個術語(即價值),而不是一種類型。

要創建一個新的X,所有人都會寫入X(),這正好是X.apply(),而從未使用new X()。決不?是的,幾乎從不。

請注意,不需要參數的情況類已過時。

+0

謝謝!是的,我不認爲你可以「分配一個類型」,除非你像'type Cool = List [Int]'那樣創建一個新類型'Cool',它是一個List [Int]權限? – Miles

+1

從技術上講,在這種情況下你並沒有創建一個新類型 - 'Cool'是一個類型別名 - 意味着它與'List [Int]'完全相同。創建一個新類型意味着'class Cool extends List [Int]'。 – sourcedelica

2

不帶參數的案例類別已棄用。改爲使用case class X()case class Me()。這樣,您將不得不通過X()調用創建X類的對象,如其他答案中所述。

或者您可以使用case object S:

case object X extends Piece { val piece: Char = 'X' }. 

事實上,如果你在這裏使用對象的情況下,你的代碼將開始工作:

case class Me extends Player { val piece: Piece = X } // Works fine 

這取決於您的要求,雖然。有可能您需要X的多個實例;那麼case對象不適合你。

+0

感謝您的支持!清除REPL抱怨棄用的原因。當你只需要一次該對象的實例時,你是否在case類上使用case對象?我注意到如果你使用大小寫對象,你不能像'case(x:X)=> println(「我是X」)那樣模式匹配,因爲'X'不再是一個類型,而是一個對'X '對象。我猜在這種情況下,你會用'if(x == X)println(「X謝謝你」)來檢查。' – Miles

+0

你可以匹配,使用'case X => println(「我是X」)' – sourcedelica

+0

@Miles,不,不需要'if'。你可以直接匹配,比如'case X => ...'。我正在寫這個,因爲很可能你沒有收到有關sourcedelica評論的通知。 –

相關問題