在Scala中,有没有办法让两个重载方法只在隐含是否可用的情况下有所不同?

时间:2012-07-19 02:03:21

标签: scala overloading

我正在编写一个访问数据库的Scala应用程序。大多数情况下,会有一个连接可用,但有时不会。我想做的事情如下:

object User {
  def authenticate(username: String, password: String)
      (implicit conn: Connection): Option[User] = {
    // use conn to grab user from db and check that password matches
    // return Some(user) if so, None if not
  }
  def authenticate(username: String, password: String): Option[User] = {
    implicit val conn = DB.getConnection()
    authenticate(username, password)
  }
}

我希望会发生的是,如果有Connection类型的隐式值,编译器将使用第一种方法。如果没有,它将使用第二个。不幸的是,我发现编译器并不那么聪明,或者如果是,我不会以正确的方式告诉它该怎么做。

所以,我的基本问题是,是否有一种方法可以编写一个需要隐式参数的方法,然后提供相同方法的重载版本,如果没有可用的参数,则创建隐式参数类型的可接受值

你可能会说,“你为什么要做这样的事情?如果你能创造一个合适类型的可接受值,为什么不总是这样做?”这是最正确的,除非我有一个开放的数据库连接,我宁愿继续使用它而不是创建一个新的。但是,如果我没有开放的数据库连接,我知道从哪里获得一个。

我的意思是,简单的答案就是给这两种方法赋予不同的名称,但我不应该这样做,天哪。但也许我会......

谢谢! 托德

2 个答案:

答案 0 :(得分:9)

您不需要重载方法。只需给你的隐式参数一个默认值,即

object User {
  def authenticate(username:String, password:String)(implicit conn:Connection = null): Option[User] = {
    val real_conn = Option(conn).getOrElse(DB.getConnection())
    // do the rest with the real_conn
  }
}

答案 1 :(得分:0)

我能想到的更清洁的解决方案是使用嵌套方法,并且正如有人建议的那样,隐含值为implicits。

class Testclass {

  def myMethod(a:Int)(implicit b:Option[Int]=None):Int = {

    def myMethodInternal(a:Int, b:Int):Int = {
      // do something
      a+b
    }
    val toUse = b.getOrElse(30)
    myMethodInternal(a,toUse)
  }
}

在你的方法中你定义了一个myMethodInternal,它没有任何含义,只是明确了参数。此方法仅在myMethod中可见,您将准备第二个参数,如下所示:

  val toUse = b.getOrElse(30)

最后用explicits参数调用你的方法:

  myMethodInternal(a,toUse)