Scala隐式用法选择
我一直在想,透明的Scala隐式用法选择,scala,implicit,Scala,Implicit,我一直在想,透明的隐式的转换是否真的是一个好主意,以及是否应该更明确地使用隐式转换。例如,假设我有一个方法,它接受日期作为参数,并且我有一个隐式转换,它将字符串转换为日期: implicit def str2date(s: String) : Date = new SimpleDateFormat("yyyyMMdd").parse(s) private def foo(d: Date) 显然,我可以通过透明的隐式的转换来调用它: foo("20090910") 我将字符串转换为日期这一事
隐式的
转换是否真的是一个好主意,以及是否应该更明确地使用隐式转换。例如,假设我有一个方法,它接受日期
作为参数,并且我有一个隐式转换,它将字符串
转换为日期
:
implicit def str2date(s: String) : Date = new SimpleDateFormat("yyyyMMdd").parse(s)
private def foo(d: Date)
显然,我可以通过透明的隐式的转换来调用它:
foo("20090910")
我将字符串转换为日期这一事实是否更为明确
class DateString(val s: String) {
def toDate : Date = new SimpleDateFormat("yyyyMMdd").parse(s)
}
implicit def str2datestr(s: String) : DateString = new DateString(s)
因此,用法看起来更像:
foo("20090910".toDate)
这样做的好处是,以后发生的事情会更清楚——我已经被我应该知道的透明隐式转换(选项到可伸缩任何人?)这种用法仍然允许我们利用隐式s的强大功能。我相信更“显式”的隐式转换方式在可读性方面比完全透明的方式要好得多,至少在本例中是这样
在我看来,当您始终可以将A
类型的对象视为可以在需要B
类型的对象时使用implicit
s完全透明地从类型A
到类型B
是可以的。例如,将字符串
隐式转换为RandomAccessSeq[Char]
总是有意义的-从概念上讲,字符串
总是可以被视为一个字符序列(例如,在C中,字符串只是一个字符序列)。调用x.foreach(println)
对所有String
s都有意义
另一方面,当A
类型的对象有时可用作B
类型的对象时,应使用更明确的转换。在您的示例中,对foo(“bar”)
的调用没有意义,会引发错误。由于Scala没有检查过的异常,对foo(s.toDate)
的调用清楚地表明可能抛出了异常(s
可能不是有效日期)。另外,foo(“bar”).toDate)
显然是错误的,而您需要查阅文档以了解为什么foo(“bar”)
可能是错误的。Scala标准库中的一个例子是通过RichString
包装器的toInt
方法将String
s转换为Int
s(String
s可以看作Int
s,但并非始终如此)。(就像上面从String到Date的转换),你本质上是说,如果你一开始就完全控制了X的编写,你会让X实现或者成为Y的一个子类
如果X实现Y有意义,则添加转换。如果没有,则可能不合适。例如,字符串实现RandomAccessSeq[Char]有意义,但字符串实现日期可能没有意义(尽管字符串实现StringDate似乎很好)
(我有点晚了,弗拉维尤有一个很好的答案,但我想补充一点,谈谈我对它的看法。)