Kotlin 有没有可能写一个;“双”字;扩展方法?
在Kotlin中,可以编写Kotlin 有没有可能写一个;“双”字;扩展方法?,kotlin,Kotlin,在Kotlin中,可以编写 class A { fun B.foo() } 然后,例如,使用(myA){myB.foo()}编写 是否可以将此作为扩展方法写入A?我的用例正在编写 with (java.math.RoundingMode.CEILING) { 1 / 2 } 我想返回1,重点是我想将操作符fun Int.div(Int)添加到RoundingMode不可能operator div必须具有Int作为接收器 您也不能将RoundingMode添加为接收器,因为只能有单功能接收
class A {
fun B.foo()
}
然后,例如,使用(myA){myB.foo()}编写
是否可以将此作为扩展方法写入A
?我的用例正在编写
with (java.math.RoundingMode.CEILING) { 1 / 2 }
我想返回1
,重点是我想将操作符fun Int.div(Int)
添加到RoundingMode
不可能operator div
必须具有Int
作为接收器
您也不能将RoundingMode
添加为接收器,因为只能有单功能接收器
不过,您可以使用Pair
作为接收器:
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
}
运算符fun Pair.div(i:Int):BigDecimal=
BigDecimal.valueOf(second.toLong()).divide(BigDecimal.valueOf(i.toLong()),first)
带(圆形模式。天花板){
println((该值为1)/2)/=>1
}
这是不可能的,Int
已经有了一个div
函数,因此,如果您决定编写一个扩展函数div
,您将无法应用它,因为成员函数胜过扩展函数
但你可以这样写:
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))
}
}
fun RoundingMode.div(x:Int,y:Int):Int{
返回if(this==RoundingMode.天花){
Math.ceil(x.toDouble()/y.toDouble()).toInt()
}否则{
Math.floor(x.toDouble()/y.toDouble()).toInt()
}
}
趣味主线(args:Array){
使用(java.math.RoundingMode.CEILING){
印地安(分区(1,2))
}
}
由于以下几个原因,这是不可能的:
Kotlin中没有“双扩展函数”的概念
您不能用扩展函数重写方法,并且运算符div
已在Int
但是,您可以使用解决这些问题
一个上下文类和一个扩展lambda(例如块:ContextClass.(->Unit
)
中缀功能(例如,使用15 div 4
而不是15/4
)
请参见下面的示例:
class RoundingContext(私有val roundingMode:roundingMode){
中缀fun Int.div(b:Int):Int{
val x=this.toBigDecimal()
val y=b.toBigDecimal()
val res=x.divide(y,舍入模式)
return res.toInt()
}
}
有趣的使用(roundingMode:roundingMode,block:RoundingContext.(->T):T{
返回(RoundingContext(roundingMode)){
块()
}
}
//试验
趣味主线(args:Array){
使用(RoundingMode.FLOOR){
println(5第2部分)//2
}
val x=使用(圆形模式天花板){
10第3组
}
println(x)//4
}
希望有帮助 我的头撞了半个小时,但这似乎是最佳解决方案。我的困惑是,在科特林,似乎有一种方法可以有两个接收者:上面的class a{fun B.foo()}
示例,其中方法foo
中有两个this
es。但是看起来没有办法让这两个参数都成为单独类型的扩展。@LouisWasserman Scala有解决这个问题的方法-隐式。但是Kotlin没有。@LouisWasserman我下面的答案(特别是“上下文类”部分)不适用于你的问题吗?这就是我看到JetBrains使用协同程序库和Ktor框架实现Kotlin魔力的方式
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
}