trait DAOContract[T <: Entity] {
// default create
def create(t: T): Option[Int]
}
trait UserContract extends DAOContract[User] {
// provide alternate create method for transactional blocks
def create(u: User)(implicit ss: Session): Either[String, Int]
...
}
// DAO provides create implementation with embedded session
class UserDAO(implicit val db: Connection)
extends DAO[User] with UserContract {
import db.Driver.Implicit._
import org.scalaquery.ql._
...
}
在控制器中
dao.create(model) // boom, no implicit session
我希望我在这里遗漏了一些东西:为什么scala编译器无法区分上面的2个create方法签名?
基本上,如果不为事务性操作(即返回Either)或独立操作提出不同的方法命名约定,我就无法重载DAO操作。
或者,我只是以错误的方式处理事情,完全可能......
答案 0 :(得分:1)
Scala禁止这样做有原因:
想象一下,您的create
方法将是:
def create(t: User): Function[Int,Something]
def create(u: User)(implicit ss: Session): Either[String, Int]
然后调用create(x)(y)
将适用于他们两个。
即使(1.)中的问题可以通过Scala编译器仔细检查函数的类型来解决,也很容易出错。在这样的设置中,程序员很容易犯错误。强制函数使用不同的名称可确保程序员始终知道他们所称的内容。
如果将方法更改为具有相同的返回类型,并且如果您愿意冒险,可以尝试这样的事情:
trait Broken {
final def foo(x: Int)(implicit session: String = null): Option[Int] =
if (session == null) foo1(x)
else foo2(x, session);
def foo1(x: Int): Option[Int]
def foo2(x: Int, session: String): Option[Int]
}
class Example extends Broken {
def foo2(x: Int, y: String) = Some(2)
def foo1(x: Int) = Some(1)
}
object Test extends App {
def withImplicit(e: Example) = {
implicit val imp = "hey"
e.foo(1) // (imp)
}
def withoutImplicit(e: Example) = e.foo(1)
println(withImplicit(new Example()));
println(withoutImplicit(new Example()));
}
当隐含值可用时,将调用相应的方法。否则,调用没有“session”参数的方法。但我强烈阻止这种做法。只是一个小错误会导致调用错误的变体,这将很难调试。
答案 1 :(得分:0)
您的创建方法有不同的sigs。一个返回一个Either,另一个返回一个Option。加上隐含的。您可能需要隐式使用并从两个
返回Option [Int]