2015-11-20 60 views
0

我已經張貼在斯卡拉用戶論壇這個問題的仿製藥,落實特質和方法

https://groups.google.com/forum/#!topic/scala-user/xlr7KmlWdWI

和我收到這我很高興回答。然而,同時我想確定這是否是唯一的結論。由於

我的問題是,比方說,我有,

trait Combinable[A] { 
    def join[B](l: List[A]): B 
} 

當我實現這個特徵與A作爲字符串和B詮釋,例如,

class CombineString extends Combinable[String] { 
    override def join[Int](strings: List[String]) = string.size 
} 

顯然,詮釋 ,加入方法旁邊,不是Scala整數類,編譯該代碼將會失敗。或者,我可以重寫我的特點爲

trait Combinable[A, B] { 
    def join(l: List[A]): B 
} 

trait Combinable[A] { 
    def join[B](l: List[A])(f: List[A] => B): B 
} 

我的問題是,我怎麼能實現如在第一個例子定義,因爲它是特質?如果第一個例子因爲定義的方式而沒有實際用途,爲什麼編譯器不會投訴?再次感謝。

+0

編譯器不會抱怨,因爲它不知道A和B通過了什麼。開發人員必須保持紀律。 –

+0

我明白,但從人的角度來看(我和其他人的回答)只有一個結果,拋出異常,編譯器引發警告是很好的。除非有其他結果我不知道 – thlim

+0

在今天的編譯器中沒有這樣的術語\實體作爲「實際使用」 – Odomontois

回答

2

您不能期望編譯器能夠理解哪種類型的組合對您有意義,但是您可以將這種意義指定爲多參數含義中類型之間的關係。

結果基本上是兩種您拒絕的方法的組合,但具有所需的語法。

兩個拒絕形式首次成爲隱式類型:

trait Combine[A, B] { 
    def apply(l: List[A]): B 
} 

接下來,您可以定義合適的類型組合及其意義

implicit object CombineStrings extends Combine[String, String] { 
    def apply(l: List[String]) = l.mkString 
} 

implicit object CombineInts extends Combine[Int, Int] { 
    def apply(l: List[Int]) = l.sum 
} 

implicit object CombinableIntAsString extends Combine[Int, String] { 
    def apply(l: List[Int]) = l.mkString(",") 
} 

最後,我們修改第二否決形式隱藏f參數隱resulution :

trait Combinable[A] { 
    def join[B](l: List[A])(implicit combine: Combine[A, B]): B = combine(l) 
} 

否W使您可以定義

val a = new Combinable[String] {} 
val b = new Combinable[Int] {} 

而且檢查

a.join[String](List("a", "b", "c")) 
b.join[Int](List(1, 2, 3)) 
b.join[String](List(1, 2, 3)) 

運行很好,而

a.join[Int](List("a", "b", "c")) 

使編譯器哭,直到你能提供StringInt之間的關係實際使用證據以隱含價格的形式

0

我的問題是,我該如何實現第一個示例中定義的特徵,因爲它是?

class CombineString extends Combinable[String] { 
    override def join[B](strings: List[String]) = null.asInstanceOf[B] 
    // or, for that matter, anything and then .asInstanceOf[B] 
} 

編譯器怎麼會知道這是不是你想要的?