【问题标题】:Kotlin Compilation Error : None of the following functions can be called with the arguments suppliedKotlin 编译错误:不能使用提供的参数调用以下函数
【发布时间】:2017-10-30 12:55:21
【问题描述】:

我有一个类,其构造函数采用 2 个 int 参数(允许为空值)。 以下是编译错误。

None of the following functions can be called with the arguments supplied: 
public final operator fun plus(other: Byte): Int defined in kotlin.Int
public final operator fun plus(other: Double): Double defined in kotlin.Int
public final operator fun plus(other: Float): Float defined in kotlin.Int
public final operator fun plus(other: Int): Int defined in kotlin.Int
public final operator fun plus(other: Long): Long defined in kotlin.Int
public final operator fun plus(other: Short): Int defined in kotlin.Int

这里是 NumberAdder 类。

class NumberAdder (num1 : Int?, num2 : Int?) {

    var first : Int? = null
    var second : Int? = null

    init{
    first = num1
    second = num2
    }

fun add() : Int?{

    if(first != null && second != null){
        return first + second
    }

    if(first == null){
        return second
    }

    if(second == null){
        return first
    }

    return null
}

}

我该如何解决这个问题?如果两者都为null,我想返回null。如果其中一个为空,则返回另一个,否则返回总和。

【问题讨论】:

  • 请注意,这与更简单的fun add = first?:0 + second?:0 几乎相同。唯一的区别是当两者都为null时它不会返回null。
  • @MichaelAnderson 相同的编译错误fun add(first : Int?, second : Int?) : Int? = first?:0 + second?:0
  • 抱歉 - 这只是一个括号问题 fun add():Int = (first:?0) + (second:?0) 适合我。

标签: int kotlin


【解决方案1】:

因为 firstsecond 是 vars,所以当您进行 if 测试时,它们不会被智能转换为非空类型。理论上,在 if-test 之后和+ 之前,另一个线程可以更改这些值。为了解决这个问题,您可以在执行 if-tests 之前将它们分配给本地 val。

fun add() : Int? {
    val f = first
    val s = second

    if (f != null && s != null) {
        return f + s
    }

    if (f == null) {
        return s
    }

    if (s == null) {
        return f
    }

    return null
}

【讨论】:

  • 解决方案有效。但是我不明白为什么在这里将变量分配给常量有效?
  • @a.r. val 的值不能更改。因此,当您进行 if 测试时,Kotlin 能够智能地将它们转换为非空类型。即使 firstsecond 在函数执行期间可以更改,fs 将保持不变。
  • 知道了。谢谢:)
【解决方案2】:

最简单的代码修复方法是使用val 而不是var

class NumberAdder (num1 : Int?, num2 : Int?) {

    val first : Int?
    val second : Int?

    init{
        first = num1
        second = num2
    }
...

我在这里使用 Kotlin 允许在构造函数中分配 val

【讨论】:

  • 可变性会影响智能铸造。 @marstrain 的回答很好地解释了这一点
【解决方案3】:

这似乎也有效。

fun main(args: Array<String>) {

    var numberAdder : NumberAdder = NumberAdder(10, 20)
    var result : Int? = numberAdder.add()
    println("$result")
}

class NumberAdder (num1 : Int?, num2 : Int?) {

    var first : Int?
    var second : Int?

    init{
        first = num1
        second = num2
    }

fun add() : Int?{

    if(first != null && second != null){
        return first as Int + second as Int
    }

    if(first == null){
        return second
    }

    if(second == null){
        return first
    }

    return null
}

}

【讨论】:

  • 这可以编译,但它(理论上)是不安全的。如果其他线程在 if-test 之后更改 firstsecond,但在强制转换或添加之前,将引发异常。我会选择我的或 voddan 的答案中的安全选项之一。
  • 是的,线程是另一个问题。但是从编译的角度来看,我认为错误可能是由于编译器无法决定在 null 的情况下需要调用谁的 plus 方法。由于 Double、Int、Float 都有 plus 方法,而且这些都是 Number 的子类。
【解决方案4】:

我在使用 assertEquals 时遇到了类似的问题。

我的代码是

assertEquals(
       expeted = 42, // notice the missing c 
       actual = foo()
)

在我修正错字后,我的 IDE 说我不能将命名参数与非 Kotlin 函数一起使用,所以我将值提取到变量中,一切都开始正常工作了。

 val expected = 42
 val actual = foo()
 assertEquals(expected, actual)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-03
    • 2021-03-19
    • 2019-06-19
    • 1970-01-01
    相关资源
    最近更新 更多