我在下面的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)
^
有没有人有这方面的想法?
答案 0 :(得分:2)
这个原因你得到了
Error:(3, 47) not found: value s
def printWithImplicit = printWithParameter(s:String)
^
是因为您定义了一个名为printWithImplicit
的函数,该函数不带参数并返回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
答案 1 :(得分:2)
你被误导了。隐式未被使用,因为该方法不获取Session
的值。让我们回顾一下:
def withSession[T](f: => T): T =
withSession { s: Session => SessionFactory.dyn.withValue(s)(f) }
因此,它需要f
类型T
,按名称传递(即,在使用时进行评估,而不是在调用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)
,所以没有任何隐含的使用。