我们有一个我们从Java API获取的Selenium WebElement,但我们已经创建了Scala类,Element和mixin更具体的特性(例如Clickable,Submittable等)。
我们的方法如下:
toScalaElement(e : WebElement) = {
e.type match {
case Input => new Element(e) with Submittable
case Link => new Element(e) with Clickable
...
case _ => new Element
}
}
返回类型始终为Element,因为它是所有情况的根类。但是,我们希望在返回时保留mixin特性。
建议在Scala的Collections API中查看构建器,但我们不确定它与此特定应用程序的关系。显然,如果有比混合特质更好的方法,那么解决方案将会受到赞赏。
更新:我改变了案例以匹配子类型而不是字符串,但问题的本质保持不变。
答案 0 :(得分:2)
我不认为这是可行的。整个方法需要有一个返回类型。对于构建器,此返回类型是通用的,因此方法调用之间可能不同,但编译器需要具有不同类型的参数来选择构建器。它看起来像这样:
case class WebElementConverter[T1, T2](f: T1 => T2) {
def convert(e: T1) = f(e)
}
object WebElementConverter {
implicit val inputConverter = WebElementConverter[Input, Element with Submittable](x => new Element(x) with Submittable)
// other converters
}
def toScalaElement[T1 <: WebElement, T2 <: Element](e : T1)(implicit b: WebElementConverter[T1, T2]) = b.convert(e)
现在你可以在这里获得理想的结果
val i = new Input // same as val i: Input = new Input
toScalaElement(i)
但不在这里:
val i: Element = new Input
toScalaElement(i) // looks for an implicit WebElementConverter[Element, <some type>]
因此,如果e
的静态类型只是WebElement
,那么构建者就无法提供帮助。
答案 1 :(得分:0)
type
是一个Scala关键字,虽然我对Selenium一无所知,但its API的google显示type
上没有WebElement
方法返回String
。因此,您似乎误解了type
关键字的作用以及模式匹配的工作原理。您应该查看这些内容,但简单地说,如果您的类Input
是WebElement
的子类,则可以在类型上与
def toScalaElement(e: WebElement) = e match {
case x: Input => new Element(x) with Submittable
// etc