我应该如何在Scala应用程序中组织隐式?

我应该如何在Scala应用程序中组织隐式?,scala,Scala,在编写了一些scala工具之后,我正在努力掌握整理代码的最佳方法——尤其是隐式。我有两个目标: 有时,我希望能够导入我所要求的隐含信息 其他时候,我只想导入所有内容 为了避免重复隐式,我提出了以下结构(与排列方式类似): 这让我可以 import StringW._ // Selective import 或者(在大多数情况下) 其他人是怎么做到的?我认为如果你不知道隐式转换是从哪里来的,那么隐式转换是危险的。在我的例子中,我将我的implicits放在Conversions类中,然后im

在编写了一些scala工具之后,我正在努力掌握整理代码的最佳方法——尤其是隐式。我有两个目标:

  • 有时,我希望能够导入我所要求的隐含信息
  • 其他时候,我只想导入所有内容
为了避免重复隐式,我提出了以下结构(与排列方式类似):

这让我可以

import StringW._ // Selective import
或者(在大多数情况下)


其他人是怎么做到的?

我认为如果你不知道隐式转换是从哪里来的,那么隐式转换是危险的。在我的例子中,我将我的
implicit
s放在
Conversions
类中,然后
import
将其尽可能接近使用


我不确定我是否喜欢从各种
trait
s中“继承”隐式,原因与实现
接口被认为是糟糕的Java实践的原因相同,这样您就可以直接使用它的常量(而首选静态导入).

我通常在对象中进行
隐式
转换,这清楚地表明导入的是
隐式
转换

例如,如果我有一个类
com.foo.bar.FilthyRichString
,隐式转换将进入
com.foo.bar.implicit.FilthyRichStringImplicit
。我知道名称有点长,但这就是为什么我们有IDE(而且Scala IDE支持越来越好)。我这样做的方式是,我觉得所有的隐式转换都能以一种清晰的方式查看是很重要的。我可以查看以下代码:


// other imports
import com.foo.bar.FilthyRichString

import com.foo.bar.util.Logger
import com.foo.bar.util.FileIO

import com.foo.bar.implicits.FilthyRichStringImplicit._
import com.foo.bar.implicits.MyListImplicit._
// other implicits
一眼就能看到这个源文件中所有的隐式转换。如果您使用导入按包分组的约定,并且在不同的包之间有一个新行,那么它们也将被收集在一起

按照同一个参数的思路,我不喜欢一个包含所有隐式转换的catch-all对象。在大型项目中,您真的会在所有源文件中使用所有隐式转换吗?我认为这样做意味着代码不同部分之间的紧密耦合

此外,catch-all对象对于文档来说也不是很好。在显式编写文件中使用的所有隐式转换的情况下,只需查看import语句即可直接跳转到隐式类的文档。对于一个catch-all对象,必须查看该对象(在大型项目中可能是巨大的),然后搜索它们所追求的隐式转换

我同意oxbow_lakes的观点,即在
trait
s中进行隐式转换是不好的,因为从中继承的诱惑,正如他所说,这是不好的做法。沿着这些思路,我将使包含隐式转换的对象成为final,以完全避免这种诱惑。如果隐式转换只是在代码中少量使用,那么他将它们导入到尽可能接近使用的地方的想法也是非常好的


--Flaviu Cipcigan

这其中的
隐式
是什么?我假设其中的所有
def
初始化都应该是隐式的?这并不是说我一定不同意这个建议,但可以指出隐式是有用的,因为它们是隐式的。如果每次使用前都添加一条import语句,那么可能会有一种说法认为您最好明确应用隐式转换。昨天回家时,我一直在仔细考虑这一点(我自己也不总是这么做)!然而,我仍然更喜欢导入而不是继承。
import World._. // Import everything
def someMethod(d: Date) ; Unit {
  import mydate.Conversions._
  val tz = TimeZone.getDefault 
  val timeOfDay = d.getTimeOfDay(tz) //implicit used here
  ...
}

// other imports
import com.foo.bar.FilthyRichString

import com.foo.bar.util.Logger
import com.foo.bar.util.FileIO

import com.foo.bar.implicits.FilthyRichStringImplicit._
import com.foo.bar.implicits.MyListImplicit._
// other implicits