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添加为接收器,因为只能有单功能接收

在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
添加为接收器,因为只能有单功能接收器

不过,您可以使用
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
    }