我很難從C++ /模板轉換到Scala。我習慣於能夠對我想要的模板參數T使用任何操作,只要我用來實例化T的任何操作都支持這些操作(基本上是編譯時Duck打字)。我無法在Scala中找到相應的成語,這將允許我使用單個類型參數定義抽象類,並且需要特定類型T的接口。在斯卡拉,我如何告訴抽象基類,類型參數T支持從Int(或浮點數,或...)的隱式轉換?
我幾乎可以工作,但我無法弄清楚如何告訴抽象類(紋理[T <:Summable [T]])T支持來自Int的轉換/構造。如何將隱式轉換添加到Summable特性中,以便Texture知道T支持轉換?
trait Summable[T] {
def += (v : T) : Unit
def -= (v : T) : Unit
}
object Int4 { implicit def int2Int4(i : Int) = new Int4(i, i, i, i) }
class Int4 (var x : Int, var y : Int, var z : Int, var w : Int) extends Summable[Int4] {
def this (v : Int) = this(v, v, v, v)
def += (v : Int4) : Unit = { x += v.x; y += v.y; z += v.z; w += v.w }
def -= (v : Int4) : Unit = { x -= v.x; y -= v.y; z -= v.z; w -= v.w }
}
abstract class Texture[Texel <: Summable[Texel]] {
var counter : Texel
def accumulate(v : Texel) : Unit = { counter += v }
def decrement() : Unit = { counter -= 1 } //< COMPILE ERROR HERE, fails to find implicit
}
class Int4Target extends Texture[Int4] {
var counter : Int4 = new Int4(0, 1, 2, 3)
}
我不追隨你反對暗示特質。對性狀的暗示是不可能的,因爲性狀不支持construtors。類可以並經常有暗示,包括像這裏所要求的那樣 - 爲什麼類可以擁有它而不是特性(除了缺少構造函數)? – 2012-02-12 07:07:24
@Daniel就是這樣。因爲類有一個構造函數,所以隱式變成了一個參數,所以變成了一個成員。有了特質,所有成員都被明確地聲明。基本上我的觀點是,如果沒有成員,你不能攜帶隱含的價值,所以它不能作爲[T <%S]出現在簽名中。即使是一個帶有隱含參數的類,使用該類實例的人也不會自動在範圍內使用它。 – Owen 2012-02-12 19:04:54