簡體   English   中英

在Scala中,如何在伴隨對象中定義隱式值/參數?

[英]In Scala, how to define a implicit value/parameter in companion object?

我從此鏈接下面看到了代碼

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的函數,該函數不帶任何參數並返回Unit 可以將其明確表示為: def printWithImplicit(): Unit

由於它不帶參數,因此它的函數體(在本例中為printWithParameter(s:String)沒有找到s定義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) }

因此,它采用類型TfwithSession名稱傳遞(即,在使用時進行評估,而不是在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) ,因此沒有地方使用任何隱式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM