编辑
好的,@Drexin提出了一个关于使用隐式转换器时类型安全性丢失/结果令人惊讶的好观点。
那么如何进行一种不太常见的转换,避免与预定义的隐式类型发生冲突?例如,我在Scala中使用JodaTime(很棒的项目!)。在同一个控制器包对象中,我的隐式定义了一个类型别名:
type JodaTime = org.joda.time.DateTime
同时还有一个隐式转换,将JodaTime类型转换为Long类型(在基于ScalaQuery构建的数据访问层中,日期存储为Long类型)
implicit def joda2Long(d: JodaTime) = d.getMillis
在这里,PreDef和我的控制器包含的隐式参数之间不存在歧义,而且控制器的隐式参数不会进入DAL,因为它们处于不同的包作用域。因此,当我执行以下操作时:
dao.getHeadlines(articleType, Some(jodaDate))
对于我来说,将隐式转换为Long是安全的,鉴于基于日期的查询被大量使用,我可以节省一些样板代码。
同样地,对于str2Int转换,控制器层接收Servlet URI参数作为String -> String。有许多情况下URI包含数字字符串,因此当我过滤路由以确定该字符串是否为Int时,我不想每次都进行stringVal.toInt;相反,如果正则表达式通过,则让隐式将字符串值转换为Int。全部代码如下:
implicit def str2Int(s: String) = s.toInt
get( """/([0-9]+)""".r ) {
show(captures(0)) // captures(0) is String
}
def show(id: Int) = {...}
在上下文中,这些隐式转换是有效的用例吗?还是说总是要显式声明?如果是后者,那么有哪些有效的隐式转换用例?
原文: 在一个包对象中,我定义了一些隐式转换,其中一个是将简单的字符串转换为整数:
implicit def str2Int(s: String) = s.toInt
通常情况下,方法接收 Int 参数但实际传入 String 时会将其转换为 Int,返回类型为 Int 但实际返回值为 String 的方法也是如此。但有些情况下,编译器会出现模糊的隐式错误,这是令人头疼的。我知道发生这种情况的情况是在尝试进行手动内联字符串到整数的转换时。例如,val i = "10".toInt。我的解决方法/技巧是在 package object 中创建一个 asInt 帮助程序以及隐式,使用 asInt("10")。那么,隐式最佳实践是什么(即通过失败学习),还是应该遵循一些指导方针,以避免陷入自己制造的陷阱?换句话说,是否应该避免简单、常见的隐式转换,只在要转换的类型是唯一的情况下使用?(即永远不会陷入歧义陷阱)谢谢反馈,当隐式按预期工作时,它们是很棒的。
"10".toInt
,当你的作用域中有一个隐式转换呢?你应该使用"10": Int
,让隐式转换来处理它。(但我同意drexin的观点,通常不应该在作用域中拥有这种隐式转换。) - Rex KerrJavaConversions
不好,JavaConverters
很好。它们也可以与类似于构建器的模式一起使用,例如在 ScalaQuery 中,但是,真正的问题是另一个问题。不要改变问题,提出一个新问题。这是免费的。 - Daniel C. Sobral