EDIT
好的,@Drexin 提出了一个很好的观点:使用隐式转换器时类型安全性的损失/令人惊讶的结果。
一个不太常见的转换怎么样,不会与 PreDef 隐式发生冲突?例如,我正在 Scala 中使用 JodaTime(很棒的项目!)。在定义隐式的同一控制器包对象中,我有一个类型别名:
type JodaTime = org.joda.time.DateTime
以及将 JodaTime 转换为 Long 的隐式(对于构建在 ScalaQuery 之上的 DAL,其中日期存储为 Long)
implicit def joda2Long(d: JodaTime) = d.getMillis
这里,PreDef 和我的控制器包隐式之间不能存在歧义,并且控制器隐式不会过滤到 DAL,因为它位于不同的包范围中。所以当我这样做时
dao.getHeadlines(articleType, Some(jodaDate))
在我看来,到 Long 的隐式转换是安全地完成的,并且考虑到基于日期的查询被大量使用,我保存了一些样板文件。
类似地,对于 str2Int 转换,控制器层接收 servlet URI 参数作为 String -> String。在很多情况下,URI 会包含数字字符串,因此当我过滤路由以确定 String 是否为 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) = {...}
在上述上下文中,这些隐式转换的有效用例是,还是总是显式的?如果是后者,那么what are有效的隐式转换用例?
ORIGINAL
In a 封装对象我定义了一些隐式转换,其中之一是简单的 String 到 Int:
implicit def str2Int(s: String) = s.toInt
一般来说,这种方法工作得很好,采用 Int 参数但接收 String 的方法会转换为 Int,就像返回类型设置为 Int 但实际返回值是 String 的方法一样。
太好了,现在在某些情况下,编译器会因可怕的模糊隐式错误:
类型为 (x: String) 的对象 Predef 中的两个方法 AugmentString
scala.collection.immutable.StringOps 和方法 str2Int(s: String) Int
是否有可能从 java.lang.String 到 ?{val 的转换函数
toInt: ?}
我知道发生这种情况的情况是在尝试进行手动内联字符串到整数转换时。例如,val i = "10".toInt
我的解决方法/黑客方法是创建一个 asInt 帮助程序以及包对象中的隐式内容:def asInt(i: Int) = i
并用作,asInt("10")
那么,隐式最佳实践是隐式的(即通过烧伤来学习),还是有一些指导方针可以遵循,以免陷入自己制造的陷阱?换句话说,是否应该避免简单、常见的隐式转换,而只在要转换的类型唯一的情况下使用? (即永远不会陷入歧义陷阱)
感谢您的反馈,隐式非常棒......当它们按预期工作时;-)