首页 > 解决方案 > 隐式转换的结果类型必须比函数中的 AnyRef 更具体

问题描述

我想写一个算法来反转scala中的数字

我没有背景

object Main {

  def main(args : Array[String]){
    println(reverse(-136))
  }

  //Par defaut les paramètres d'une fonction scala sont immutables
  def reverse(x : Int):Int={
    var x1:Int = Math.abs(x)
    var rev:Int = 0;

    while (x1 > 0){
      var pop:Int  = x1 % 10
      x1 /=10
      if(rev > Int.MaxValue/10 || ((rev eq Int.MaxValue/ 10) && pop > 7)) 0.##
      if (rev < Int.MinValue / 10 || ((rev eq Int.MinValue  / 10) && pop < -8)) 0.##
      rev = (rev * 10) + pop
    }
    if (x < 0) rev *= -1
    return rev
  }
}

错误:(15, 58) 隐式转换的结果类型必须比 AnyRef 更具体

   if(rev > Int.MaxValue/10 || ((rev eq Int.MaxValue/ 10) && pop > 7)) 0.##

标签: scala

解决方案


eq是Scala中的指针比较运算符,因此用于比较类型的值AnyRef。但是您正在比较整数值,并且Ints 派生自AnyVal,而不是AnyRef

要比较Int数量是否相等(或Scala中的任何其他东西是否相等),请改用==运算符。

顺便说一句,您的任何if陈述都不会影响结果,因为您没有更改任何内容并丢弃结果。(并且,正如其他人所评论的那样,0.##相当于0.hashCode,它恰好具有值 0Int值 0。我无法想象这就是你真正需要的。)

更新代码的功能版本如下所示:

import scala.annotation.tailrec
import scala.util.Try

// By extending from the App trait, we do not need a main function.
object Main
extends App {

  println(reverse(-136))

  // Return a decimal number with the digits in x reversed. If an error occurs (such as an
  // overflow), then the exception will be returned wrapped in a Failure instance.
  // If it succeeds, the result is wrapped in a Success.
  def reverse(x: Int): Try[Int] = {

    // If x is negative, we need to subtract values; if positive, we need to add them. In
    // both cases, we need to trap integer overflows. Math.subtractExact does the former,
    // Math.addExact does the latter.
    //
    // If an overflow occurs, an ArithmeticException will be thrown.
    val op: (Int, Int) => Int = if(x < 0) Math.subtractExact else Math.addExact

    // Process the next digit.
    //
    // Note: this function will throw an exception if an overflow occurs (of type
    // ArithmeticException).
    @tailrec
    def nextDigit(value: Int, result: Int): Int = {

      // If value is now 0, then return the result.
      if(value == 0) result

      // Otherwise, process the right-most digit of value into a new result.
      else {

        // Take the right-most digit of value (removing the sign).
        val digit = Math.abs(value % 10)

        // Perform the next iteration, updating value and result in the process.
        //
        // Note: The result is updated according to the "op" we defined above.
        nextDigit(value / 10, op(Math.multiplyExact(result, 10), digit))
      }
    }

    // Perform the conversion by looking at the first digit. Convert any thrown exceptions
    // to failures.
    Try(nextDigit(x, 0))
  }
}

需要注意的几点:

  1. 没有var声明,也没有任何while循环。(这些是过程式编程的症状,而Scala鼓励将函数式编程作为替代方案。)while循环被尾递归函数取代。(@tailrec告诉Scala编译器nextDigit必须是尾递归的;如果不是,编译器将发出编译时错误。)var声明被这个递归函数的参数替换。
  2. reverse功能已完全定义。它不会抛出异常(任何抛出的异常都会nextDigit被处理并且不会传递给调用者),并且x会为所提供的每个值返回一个结果;对于那些无法反转的值(例如,因为它们溢出 32 整数结果),Failure而是返回一个实例。
  3. 没有return声明;考虑到它的功能性,在Scala中使用 ofreturn被认为是糟糕的风格。

如果您对此有任何疑问,请添加评论,我会尝试回答。


推荐阅读