函数中隐式转换的结果类型必须比AnyRef更具体

时间:2019-01-21 23:59:11

标签: scala

我想写一个在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.##

2 个答案:

答案 0 :(得分:6)

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

要比较Int数量是否相等(或在此情况下, Scala 中的其他任何值),请使用==运算符。

偶然地,您的if语句都不会影响结果,因为您没有更改任何内容并丢弃结果。 (而且,正如其他人所评论的,0.##等同于0.hashCode,而Int的值恰好是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)) } } 的值恰好是0。实际需要。)

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

var

一些注意事项:

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

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

答案 1 :(得分:3)

您可以将Int更改为String,这很容易反转,然后再次将其更改回来,但是您必须测试-字符。

x.toString.reverse.foldLeft(0)((n,c) => if (c=='-') -1*n else n*10 + c.asDigit)

如果您希望将其全部保留在数字字段中...

Stream.iterate(x)(_/10)       //an infinite reduction of the original number
      .takeWhile(_ != 0)      //no longer infinite
      .map(_ % 10)            //reduce to single digits
      .foldLeft(0)(_*10 + _)  //fold all the digits back into an Int