scala - 避免使用隐式扩大类型?
问题描述
试图避免使用隐式类扩大特定的文字类型:
implicit class keepAsListOfInt(val listOfInt: List[Int]) extends AnyVal {
def :+(long: Long): List[Int] = listOfInt :+ long.toInt
}
// Won't compile - already widened to List[AnyVal]
val listOfInt: List[Int] = List(1) :+ 2L
但是由于编译器已经扩展了表达式List(1) :+ 2L
,List[AnyVal]
因此永远不会调用隐式转换。我可以以某种方式隐式强制转换吗?
更新 - 感谢sachav的回复和Alexey的有效关注,以下代码似乎可以完成这项工作:
import scala.language.implicitConversions
implicit def listAnyValToListInt(l: List[AnyVal]): List[Int] = l.map {
case n: Int => n
case n: Long if n < Int.MinValue =>
throw new IllegalArgumentException("Can't cast too small Long to Int: " + n)
case n: Long if n > Int.MaxValue =>
throw new IllegalArgumentException("Can't cast too big Long to Int: " + n)
case n: Long => n.toInt
case v =>
throw new IllegalArgumentException("Invalid value: " + v)
}
val valid: List[Int] = List(1) :+ 2
val invalid: List[Int] = List(1) :+ 30000000000L // fails at runtime
如果有编译时解决方案,它仍然会很好。
解决方案
适用的方法:+
在List
类本身上可用,因此编译器不会费心查找由隐式添加的具有相同名称的任何其他方法。
我认为最好的解决方案可能是WartRemover,因为碰巧这种情况被内置的AnyVal
wart覆盖。
推荐阅读
- spring - Spring MVC 错误:无法将 java.lang.String 类型的属性值转换为所需类型
- jsf - 当我有一个用于 inputText 的转换器时,ValueChangeListener 没有为 h:inputText 触发
- mysql - Mysql:无法设置 lower_case_table_names 变量
- vulkan - Vulkan 每帧更新描述符
- mongodb - 如何使用新 ID 进行 mongoexport 和 mongoimport 集合但保持关系
- android - Desugar 项目运行失败
- amazon-web-services - cloudformation windows userdata cfn-init.exe 行尾问题
- android - 如何构建具有 2 列的表,每列中的行数不同?
- python - logger.disabled 稍后在 python 日志记录模块中检查。理由是什么?
- java - Spring MappingJackson2HttpMessageConverter 没有被触发?