在Kotlin中可以写
class A {
fun B.foo()
}
,然后例如写with (myA) { myB.foo() }
。
是否可以将其作为扩展方法写在A
上?我的用例是写作
with (java.math.RoundingMode.CEILING) { 1 / 2 }
我想返回1
,关键是我想将operator fun Int.div(Int)
添加到RoundingMode
。
答案 0 :(得分:2)
不,这不可能。 operator div
必须具有Int
作为接收者。
您也不能添加RoundingMode
作为接收者,因为只能有一个功能接收者。
不过,您可以使用Pair<RoundingMode, Int>
作为接收者:
operator fun Pair<RoundingMode, Int>.div(i: Int): BigDecimal =
BigDecimal.valueOf(second.toLong()).divide(BigDecimal.valueOf(i.toLong()), first)
with(RoundingMode.CEILING) {
println((this to 1) / 2) // => 1
}
答案 1 :(得分:1)
这是不可能的,Int
已经具有div
函数,因此,如果您决定编写扩展函数div
,则将无法应用它,因为member功能胜过扩展功能。
您可以这样写:
fun RoundingMode.div(x: Int, y: Int): Int {
return if (this == RoundingMode.CEILING) {
Math.ceil(x.toDouble() / y.toDouble()).toInt()
} else {
Math.floor(x.toDouble() / y.toDouble()).toInt()
}
}
fun main(args: Array<String>) {
with(java.math.RoundingMode.CEILING) {
println(div(1,2))
}
}
答案 2 :(得分:0)
由于以下几个原因,这是不可能的:
div
中已经定义了运算符Int
但是,您可以通过以下方法解决这些问题
block: ContextClass.() -> Unit
)15 div 4
代替15 / 4
)请参见以下示例:
class RoundingContext(private val roundingMode: RoundingMode) {
infix fun Int.div(b: Int): Int {
val x = this.toBigDecimal()
val y = b.toBigDecimal()
val res = x.divide(y, roundingMode)
return res.toInt()
}
}
fun <T> using(roundingMode: RoundingMode, block: RoundingContext.() -> T): T {
return with(RoundingContext(roundingMode)) {
block()
}
}
// Test
fun main(args: Array<String>) {
using(RoundingMode.FLOOR) {
println(5 div 2) // 2
}
val x = using(RoundingMode.CEILING) {
10 div 3
}
println(x) // 4
}
希望有帮助!