我有一个带有一堆实用程序方法的Scala对象,每个方法都使用隐式方法参数s
object MyObject {
def a(implicit s:String) = ???
def b(implicit s:String) = ???
def c(implicit s:String) = ???
}
我不喜欢在每个参数列表中需要此implicit s:String
的事实。有没有办法只设置变量s
一次(即首次访问对象时)。对于一堂课我会做这样的事情:
class MyClass(implicit s:String) {
def a() = ???
def b() = ???
def c() = ???
}
答案 0 :(得分:5)
简短回答是"不,你不能"。
为什么呢?由于s
不是变量,因此它是一个参数。因此它不会在运行时(例如,在第一次加入时)设置,而是在编译时解析(因为它是隐式的)。
当您在代码的一部分中编写MyObject.a
时,编译器将检查当前作用域中是否存在隐式String
定义,并将s
使用该定义}。
如果您在代码的另一部分中使用a
,它将使用该范围中的隐式定义,这可能完全不同。
所有这些都在编译时验证,因此它与在运行时访问方法的时间无关(尽管访问它们时可能会更改s
的运行时值,如果您有可变的含义,应该避免)。
如果您总是希望对s
使用相同的定义,为什么不简单地将此定义放在您的对象中?或者将其作为隐式导入:
object MyObject {
implicit def myImplicitString: String = ??? //first possibility
import MyImplicits.stringImplicit //second possibility, if stringImplicit is indeed defined as implicit
}
最重要的是,如果您不想传递隐式参数,则需要将其放在范围内,并且因为您的范围是object
,所以它必须始终相同。
然而,使用class
有什么问题?它可以为您提供所需的内容(避免重复隐式参数),而无需更改您的调用(仅使用new MyClass().a
代替MyObject.a
,如果您将其定义为MyCaseClass().a
,则使用case class
1}})。如果对象中有其他字段,则可以始终将它们放在类的伴随对象中,以最大限度地减少实例化时的开销。