【问题标题】:In Scala, how to define a implicit value/parameter in companion object?在 Scala 中,如何在伴随对象中定义隐式值/参数?
【发布时间】:2015-05-11 17:29:12
【问题描述】:

我从这个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的值,所以我尝试在一个简单的sn-p中重现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)
                                             ^

有人对此有想法吗?

【问题讨论】:

    标签: scala session implicit


    【解决方案1】:

    你被误导了。未使用隐式,因为该方法没有获取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()
    }
    

    这里它需要一个从SessionT(将是s: Session => SessionFactory.dyn.withValue(s)(f))的函数,创建一个Session,然后使用该会话来调用该函数通过了。会话创建只是一个new Session(this),所以没有任何隐式使用。

    【讨论】:

      【解决方案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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-24
        • 1970-01-01
        • 2020-01-14
        • 1970-01-01
        • 2016-08-24
        • 2019-10-11
        • 1970-01-01
        • 2016-02-27
        相关资源
        最近更新 更多