2016-11-14 169 views
3

通用操作我有以下科特林,對數

abstract interface Vec2t<T : Number> {  
    var x: T 
    var y: T 
} 

data class Vec2(override var x: Float, override var y: Float) : Vec2t<Float>

和我有一個界面,我定義的一些操作,例如:

interface fun_vector2_common { 

    fun abs(res: Vec2, a: Vec2): Vec2 { 
     res.x = glm.abs(a.x) 
     res.y = glm.abs(a.y) 
     return res 
    } 
} 

是否有可能實現,讓我們說abs,通過使用泛型?

interface fun_vector2_common<T : Number> { 

    fun abs(res: Vec2t<T>, a: Vec2t<T>): Vec2t<T> { 
     res.x = glm.abs(a.x) // error 
     res.y = glm.abs(a.y) // error 
     return res 
    } 
} 

然後根據類型將相應的glm.abs()調用?

上面的代碼失敗,因爲它預計,很明顯,一個glm.abs(n: Number)

+0

的可能的複製[如何實現在科特林每個數字式地面模?](https://stackoverflow.com/questions/38052008/how-to-implement-floor-modulo-for-every-number-type-in​​-kotlin) – outis

+0

已經提出了各種解決方案。有一個[結構類型]的請求(https://youtrack.jetbrains.com/issue/KT-218)被添加到Kotlin,但它似乎沒有牽引力。最近一個[類型類]的KEEP(https://github.com/Kotlin/KEEP/pull/87)被創建。關於[擴展類型](https://discuss.kotlinlang.org/t/extension-types-for-kotlin/1390/14)也有廣泛的討論,它們基本上是類型類,但是作爲擴展函數的擴展而出現。 – outis

回答

2

不幸的是there's no clean way to have generic abs function

object glm { 
    fun <T : Number> abs(x: T): T { 
     val absoluteValue: Number = when (x) { 
      is Double -> Math.abs(x) 
      is Int -> Math.abs(x) 
      is Float -> Math.abs(x) 
      is BigDecimal -> x.abs() 
      is BigInteger -> x.abs() 
      else -> throw IllegalArgumentException("unsupported type ${x.javaClass}") 
     } 
     @Suppress("UNCHECKED_CAST") 
     return absoluteValue as T 
    } 
} 

這將使它能夠在您的上下文中使用:您可以通過以下abs定義工作,它周圍

fun abs(res: Vec2, a: Vec2): Vec2 { 
    res.x = glm.abs(a.x) 
    ... 
}