Scala隐式用法选择 [英] Scala implicit usage choices

查看:81
本文介绍了Scala隐式用法选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在想 transparent implicit转换是否真的是一个好主意,以及更多地使用隐式(um),显式可能实际上更好.例如,假设我有一个接受Date作为参数的方法,并且我有一个隐式转换,它将String转换为Date:

implicit def str2date(s: String) : Date = new SimpleDateFormat("yyyyMMdd").parse(s)

private def foo(d: Date)

那么显然我可以通过透明的implicit转换来调用它:

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)

这样做的好处是,以后会更清楚地了解发生了什么-我已经被我应该知道的透明implicit转换(OptionIterable任何人?)困住了好几次.这种用法仍使我们能够利用implicit s的功能.

我认为,至少在此示例中,在可读性方面,比完全透明的隐式转换更显式"的方式要好得多.

我认为,当您可以始终查看类型为A的对象时,完全透明地使用implicit从类型A到类型B是可以的在需要B类型的对象时使用.例如,将String隐式转换为RandomAccessSeq[Char]总是有意义的-从概念上讲,String始终可以视为字符序列(在C中,字符串为 just 例如一个字符序列).呼叫x.foreach(println)对于 all String s都是有意义的.

另一方面,当类型A的对象可以有时用作类型B的对象时,应使用更明确的转换.在您的示例中,对foo("bar")的调用没有任何意义,并且会引发错误.由于Scala没有检查异常,因此对foo(s.toDate)的调用清楚地表明可能引发了异常(s可能不是有效日期).同样,foo("bar".toDate)显然看起来是错误的,而您需要查阅文档以了解为什么foo("bar")可能是错误的. Scala标准库中的一个示例是通过RichString包装器的toInt方法从StringInt的转换(String可以看作是Int,但不能一直).

I've been wondering whether transparent implicit conversions are really such a good idea and whether it might actually be better to use implicits more, um, explicitly. For example, suppose I have a method which accepts a Date as a parameter and I have an implicit conversion which turns a String into a Date:

implicit def str2date(s: String) : Date = new SimpleDateFormat("yyyyMMdd").parse(s)

private def foo(d: Date)

Then obviously I can call this with a transparent implicit conversion:

foo("20090910")

Would it be better to make the fact that I am converting the string into a date more explicit?

class DateString(val s: String) { 
  def toDate : Date = new SimpleDateFormat("yyyyMMdd").parse(s) 
}

implicit def str2datestr(s: String) : DateString = new DateString(s)

So then the usage looks more like:

foo("20090910".toDate)

The advantage of this is that it is clearer later on what is happening - I've been caught out a few times now by transparent implicit conversions I should know about (Option to Iterable anyone?) and this usage still allows us to take advantage of the power of implicits.

解决方案

I believe that the more "explicit" way of doing implicit conversions is much better in terms of readability than the fully transparent one, at least in this example.

In my opinion, using implicits fully transparently from type A to type B is OK when you can always view an object of type A as being able to be used whenever and object of type B is needed. For example, the implicit conversion of a String to a RandomAccessSeq[Char] always makes sense - a String can always, conceptually, be viewed as a sequence of characters (in C, a string is just a sequence of characters, for example). A call to x.foreach(println) makes sense for all Strings.

On the other hand, the more explicit conversions should be used when an object of type A can sometimes be used as an object of type B. In your example, a call to foo("bar") does not makes sense and throws an error. As Scala does not have checked exceptions, a call to foo(s.toDate) clearly signals that there might be an exception thrown (s might not be a valid date). Also, foo("bar".toDate) clearly looks wrong, while you need to consult documentation to see why foo("bar") might be wrong. An example of this in the Scala standard library is conversions from Strings to Ints, via the toInt method of the RichString wrapper (Strings can be seen as Ints, but not all the time).

这篇关于Scala隐式用法选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆