在 Scala 中,如何在伴随对象中定义隐式 value/parameter?
In Scala, how to define a implicit value/parameter in companion object?
我看到下面的代码 Link
abstract class SessionFactory {
protected[squery] def createConnection(): Connection
def createSession(): Session = new Session(this)
def withSession[T](f: Session => T): T = {
val s = createSession()
try { f(s) } finally s.close()
}
def withSession[T](f: => T): T =
withSession { s: Session => SessionFactory.dyn.withValue(s)(f) }
}
object SessionFactory {
private val dyn = new DynamicVariable[Session](null)
implicit def getThreadSession: Session = {
val s = dyn.value
if(s eq null)
throw new SQLException("No implicit thread session available; getThreadSession() can only be used within a withSession block")
else s
}
}
我不知道 def withSession[T](f: => T): T
如何获得 s:Session
的值,所以我尝试在一个简单的片段中重现 implicit
的这种用法:
class printTest {
def printWithParameter(s:String) = println(s)
def printWithImplicit = printWithParameter(s:String)
}
object printTest {
implicit val sp:String = "implicit value"
implicit def getString:String = "implicit def"
}
val pt = new printTest()
pt.printWithImplicit
但是 printTest
不起作用,编译器说:
Error:(3, 47) not found: value s
def printWithImplicit = printWithParameter(s:String)
^
有人对此有想法吗?
这就是你得到
的原因
Error:(3, 47) not found: value s
def printWithImplicit = printWithParameter(s:String)
^
是因为你定义了一个名为printWithImplicit
的函数,它不带参数,return Unit
。可以显式写成:def printWithImplicit(): Unit
因为它没有参数,所以它的函数体,在这个例子中,printWithParameter(s:String)
,找不到s
的定义
回到你的问题。
您需要 import printTest.sp
在
之前
val pt = new printTest()
pt.printWithImplicit
我把你的例子简化了一点:
class printTest {
def printWithParameter(s:String) = println(s)
def printWithImplicit(implicit s:String) = printWithParameter(s)
}
object printTest {
implicit val sp:String = "implicit value"
}
import printTest.sp
val pt = new printTest()
pt.printWithImplicit
你被误导了。未使用隐式,因为该方法 不是 获取 Session
的值。让我们回顾一下:
def withSession[T](f: => T): T =
withSession { s: Session => SessionFactory.dyn.withValue(s)(f) }
因此,它采用类型为 T
的 f
,按名称传递(也就是说,它在使用时计算,而不是在调用 withSession
时计算)。然后它调用 withSession
将函数从 Session
传递到 T
。它 不 创建 Session
,它 请求 Session
,可以这么说。那么让我们看看它叫什么:
def withSession[T](f: Session => T): T = {
val s = createSession()
try { f(s) } finally s.close()
}
这里它需要一个从Session
到T
的函数(这将是s: Session => SessionFactory.dyn.withValue(s)(f)
),创建一个Session
,然后使用该会话调用传递的函数。会话创建只是一个 new Session(this)
,因此没有任何隐式被使用。
我看到下面的代码 Link
abstract class SessionFactory {
protected[squery] def createConnection(): Connection
def createSession(): Session = new Session(this)
def withSession[T](f: Session => T): T = {
val s = createSession()
try { f(s) } finally s.close()
}
def withSession[T](f: => T): T =
withSession { s: Session => SessionFactory.dyn.withValue(s)(f) }
}
object SessionFactory {
private val dyn = new DynamicVariable[Session](null)
implicit def getThreadSession: Session = {
val s = dyn.value
if(s eq null)
throw new SQLException("No implicit thread session available; getThreadSession() can only be used within a withSession block")
else s
}
}
我不知道 def withSession[T](f: => T): T
如何获得 s:Session
的值,所以我尝试在一个简单的片段中重现 implicit
的这种用法:
class printTest {
def printWithParameter(s:String) = println(s)
def printWithImplicit = printWithParameter(s:String)
}
object printTest {
implicit val sp:String = "implicit value"
implicit def getString:String = "implicit def"
}
val pt = new printTest()
pt.printWithImplicit
但是 printTest
不起作用,编译器说:
Error:(3, 47) not found: value s
def printWithImplicit = printWithParameter(s:String)
^
有人对此有想法吗?
这就是你得到
的原因Error:(3, 47) not found: value s
def printWithImplicit = printWithParameter(s:String)
^
是因为你定义了一个名为printWithImplicit
的函数,它不带参数,return Unit
。可以显式写成:def printWithImplicit(): Unit
因为它没有参数,所以它的函数体,在这个例子中,printWithParameter(s:String)
,找不到s
回到你的问题。
您需要 import printTest.sp
在
val pt = new printTest()
pt.printWithImplicit
我把你的例子简化了一点:
class printTest {
def printWithParameter(s:String) = println(s)
def printWithImplicit(implicit s:String) = printWithParameter(s)
}
object printTest {
implicit val sp:String = "implicit value"
}
import printTest.sp
val pt = new printTest()
pt.printWithImplicit
你被误导了。未使用隐式,因为该方法 不是 获取 Session
的值。让我们回顾一下:
def withSession[T](f: => T): T =
withSession { s: Session => SessionFactory.dyn.withValue(s)(f) }
因此,它采用类型为 T
的 f
,按名称传递(也就是说,它在使用时计算,而不是在调用 withSession
时计算)。然后它调用 withSession
将函数从 Session
传递到 T
。它 不 创建 Session
,它 请求 Session
,可以这么说。那么让我们看看它叫什么:
def withSession[T](f: Session => T): T = {
val s = createSession()
try { f(s) } finally s.close()
}
这里它需要一个从Session
到T
的函数(这将是s: Session => SessionFactory.dyn.withValue(s)(f)
),创建一个Session
,然后使用该会话调用传递的函数。会话创建只是一个 new Session(this)
,因此没有任何隐式被使用。