代码之家  ›  专栏  ›  技术社区  ›  oxbow_lakes

scala隐式用法选择

  •  23
  • oxbow_lakes  · 技术社区  · 16 年前

    我一直在想 透明的 implicit 转换真的是个好主意,是否真的可以更好地使用implicit,嗯, 明确地 . 例如,假设我有一个方法接受 Date 作为参数,我有一个隐式转换,它将 String 变成一个 日期 :

    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)
    

    这样做的好处是,以后会更清楚地了解正在发生的事情——我已经被透明的方式吸引了好几次了。 隐性的 我应该知道的转换( Option Iterable 有人吗?)这种用法仍然允许我们利用 隐性的 S.

    2 回复  |  直到 11 年前
        1
  •  43
  •   Matt Ball    12 年前

    我相信在可读性方面,进行隐式转换的更“显式”的方法要比完全透明的方法好得多,至少在本例中是这样。

    在我看来,使用 implicit 从类型完全透明 A 键入 B 你什么时候可以 总是 查看类型的对象 可以在任何时间和类型的对象上使用 是需要的。例如,隐式转换 String 到A RandomAccessSeq[Char] 总是有意义的-a 在概念上,可以始终被视为字符序列(在C中,字符串是 只是 例如,字符序列)。对…的呼唤 x.foreach(println) 有道理 全部的 S.

    另一方面,当对象类型为 可以 有时 用作类型的对象 . 在您的示例中,调用 foo("bar") 不合理并引发错误。由于scala没有检查异常,因此调用 foo(s.toDate) 清楚地表明可能会引发异常( s 可能不是有效日期)。也, foo("bar".toDate) 显然看起来是错误的,而您需要查阅文档以了解原因 Fo(“bar”) 可能是错的。scala标准库中的一个例子是 S to Int S,通过 toInt 方法 RichString 包装纸(包装纸) S可视为 int S,但不是 总是 )。

        2
  •  13
  •   Peter Mortensen icecrime    13 年前

    当您从x到y进行隐式转换时(如从上面的字符串到日期的转换),您基本上是说,如果您首先完全控制了编写x,那么您将使x实现或成为y的子类。

    如果x实现y是合理的,那么添加转换。如果没有,那么可能是不合适的。例如,字符串实现randomaccessseq[char]是有意义的,但字符串实现日期可能没有意义(尽管实现string date的字符串似乎很好)。

    (我有点晚了,弗拉维尤有一个很好的答案,但我想就我对暗示的看法添加一个评论。)

    推荐文章