在Scala中,我怎么可以委托隐式转换的导入到我的范围,这样我不必有一个大的“环境”类,它提供两个库函数/值(对于DSL我创造),以及隐转换?
总之,我可以将我的隐式转换,从一个对象,而且还有当我写它的输入:
进口MyDslEnvironment._
?
这样做的目的是为了让我的框架简单,重量轻的进口和使用,因为只有一个import语句为用户提供了我的DSL /框架所需的功能意义。
PS:在任何人火焰我 - 是的,我知道的陷阱和污秽可能来自隐式转换的。
在Scala中,我怎么可以委托隐式转换的导入到我的范围,这样我不必有一个大的“环境”类,它提供两个库函数/值(对于DSL我创造),以及隐转换?
总之,我可以将我的隐式转换,从一个对象,而且还有当我写它的输入:
进口MyDslEnvironment._
?
这样做的目的是为了让我的框架简单,重量轻的进口和使用,因为只有一个import语句为用户提供了我的DSL /框架所需的功能意义。
PS:在任何人火焰我 - 是的,我知道的陷阱和污秽可能来自隐式转换的。
我的倾向是把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中显得做作必须做出充分的类的静态成员的只是效用函数。 包装对象作为非常优雅的名字空间,这些实用程序,包括隐式转换。
这可以用平凡性状来实现。 如需要(实现模块化)在尽可能多的特点正好可以确定你隐式转换,并在单个对象(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)
你可以在实际上把所有的代码( Foo
, Bar
和Baz
在我上面的例子中)内部的特质,而不是只是你的隐式转换(这可能需要使用自类型标注)。 此时,你会已经基本上实施了(中)著名蛋糕图案的变种之一。 见http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di/