隐式转换的斯卡拉委托进口(Scala delegate import of implicit con

2019-09-24 03:42发布

在Scala中,我怎么可以委托隐式转换的导入到我的范围,这样我不必有一个大的“环境”类,它提供两个库函数/值(对于DSL我创造),以及隐转换?

总之,我可以将我的隐式转换,从一个对象,而且还有当我写它的输入:

进口MyDslEnvironment._

这样做的目的是为了让我的框架简单,重量轻的进口和使用,因为只有一个import语句为用户提供了我的DSL /框架所需的功能意义。

PS:在任何人火焰我 - 是的,我知道的陷阱和污秽可能来自隐式转换的。

Answer 1:

我的倾向是把implicits在一个包对象。

假设你的工作将在包com.acme.mydsl定义。 你的源文件被安排在一个目录层次结构COM>极致>看MyDSL。 在目录看MyDSL,定义像这样的对象:

package com.acme; //we are in the mydsl dir, but note no mydsl in
                  //in the package declaration

package object mydsl {

   implicit def idioticallyStringsAre5( s : String ) : Int = 5

   //define other utilities that should be available within
   //the package or importable

}

现在,你可以这样做:

scala> import com.acme.mydsl._
import com.acme.mydsl._

scala> def sum( a : Int, b : Int ) = a + b
sum: (a: Int, b: Int)Int

scala> sum("hello", "there")
res0: Int = 10

通过导入进口com.acme.mydsl._,你把所有的数据包级的功能定义,包括隐式转换。

我真的很喜欢包对象。 它总是在Java中显得做作必须做出充分的类的静态成员的只是效用函数。 包装对象作为非常优雅的名字空间,这些实用程序,包括隐式转换。



Answer 2:

这可以用平凡性状来实现。 如需要(实现模块化)在尽可能多的特点正好可以确定你隐式转换,并在单个对象(MyDslEnvironment)混合特征。 举例:

case class Foo( value: Int )
case class Bar( value: String )
object Baz {
  def test( foo: Foo, bar: Bar ) { println( foo + "," + bar ) }
}

trait ImplicitEnv1 {
  implicit def toFoo( value: Int ) = Foo( value )
}

trait ImplicitEnv2 {
  implicit def toBar( value: String ) = Bar( value )
}

object MyDslEnvironment extends ImplicitEnv1 with ImplicitEnv2

然后,你可以这样做:

scala> import MyDslEnvironment._
import MyDslEnvironment._
scala> Baz.test( 123, "hello" )
Foo(123),Bar(hello)

你可以在实际上把所有的代码( FooBarBaz在我上面的例子中)内部的特质,而不是只是你的隐式转换(这可能需要使用自类型标注)。 此时,你会已经基本上实施了(中)著名蛋糕图案的变种之一。 见http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di/



文章来源: Scala delegate import of implicit conversions