scala - 隐式转换的结果类型必须比函数中的 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.##
解决方案
eq
是Scala中的指针比较运算符,因此用于比较类型的值AnyRef
。但是您正在比较整数值,并且Int
s 派生自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))
}
}
需要注意的几点:
- 没有
var
声明,也没有任何while
循环。(这些是过程式编程的症状,而Scala鼓励将函数式编程作为替代方案。)while
循环被尾递归函数取代。(@tailrec
告诉Scala编译器nextDigit
必须是尾递归的;如果不是,编译器将发出编译时错误。)var
声明被这个递归函数的参数替换。 - 该
reverse
功能已完全定义。它不会抛出异常(任何抛出的异常都会nextDigit
被处理并且不会传递给调用者),并且x
会为所提供的每个值返回一个结果;对于那些无法反转的值(例如,因为它们溢出 32 整数结果),Failure
而是返回一个实例。 - 没有
return
声明;考虑到它的功能性,在Scala中使用 ofreturn
被认为是糟糕的风格。
如果您对此有任何疑问,请添加评论,我会尝试回答。
推荐阅读
- html - 生产版本未正确显示模型属性值
- java - 将 Liquibase XML 更改日志转换为 YAML 格式后,出现“关系已存在”错误
- javascript - Nuxt.JS:如何在 vue 文件中获取 post 参数数据
- python - sns catplot 导致函数打印在装饰器定时器函数之外
- ios - 获取文件“xxx”无法打开,因为您在导入时无权查看它
- javascript - 反应:请帮助==>为什么控制台日志在第一次渲染时打印两次
- php - 首先使用学说 findBy() 对 NULL 值进行排序
- excel - 转到标签功能的问题
- reactjs - 如何解决“键入 Promise
没有与 T 型相同的属性”错误? - python - 获取 RuntimeError:无法使用多输入 Keras 模型创建链接(名称已存在)