使用Scala中的返回值保留mixin特征

时间:2012-01-26 04:15:00

标签: scala

我们有一个我们从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中查看构建器,但我们不确定它与此特定应用程序的关系。显然,如果有比混合特质更好的方法,那么解决方案将会受到赞赏。

更新:我改变了案例以匹配子类型而不是字符串,但问题的本质保持不变。

2 个答案:

答案 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关键字的作用以及模式匹配的工作原理。您应该查看这些内容,但简单地说,如果您的类InputWebElement的子类,则可以在类型上与

匹配
def toScalaElement(e: WebElement) = e match { 
  case x: Input => new Element(x) with Submittable
  // etc