Scala中构造函数的通用参数

时间:2015-11-17 16:10:28

标签: java scala generics constructor

考虑以下设计的Java示例:

public class Example {

    private final Object value;
    private final List<?> aListOfTheseThings;

    public <T> Example(final T t, final List<T> aListOfTheseThings) {
        this.value = t;
        this.aListOfTheseThings = aListOfTheseThings;
    }

}

本例中我关心的是:

  1. Example未参数化
  2. 构造函数 paremeterized并确保无论您传入的是什么,列表都以相同类型的t
  3. 进行参数化

    (这是一个人为的例子,我并不真正关心(2),但我真的关心那里有一个类型参数,这在类的定义中没有提到。)

    现在在Scala中我尝试了以下内容:

    class Example private[this](
      private val value: AnyRef,
      private val aListOfTheseThings: List[_]) {
    
      def this[T](t: T, aListOfTheseThings: List[T]) {
        this(t, aListOfTheseThings)
      }
    }
    

    ......但这是不可能的。显然,类型参数在构造函数中无效(在this中)。

    是否有机会将上述Java代码翻译成Scala?

2 个答案:

答案 0 :(得分:7)

也许这有帮助:

sealed trait Example

object Example {
  def apply[T <: AnyRef](t:T, aListOfTheseThings: List[T]): Example = 
    new ExampleImpl(t, aListOfTheseThings)

  private class ExampleImpl(
    val value: AnyRef, 
    val aListOfTheseThings: List[_]) extends Example 
}

这使得类Example的私有构造函数成为可能。价值和aListOfTheseThings不会通过Example特征访问(除非您可以访问)

答案 1 :(得分:6)

Nyavro建议使用帮助apply方法是一个很好的方法。在某些情况下可能适用的另一种选择是子类化:

trait Example {
  val value: Any
  val things: List[_]
}

class SameTypeExample[T](val value: T, val things: List[T]) extends Example

子类化的优点是valuethings存储相同类型的约束不会丢失,并且可以通过模式匹配重新发现:

def handle(example: Example) = example match {
  case st: SameTypeExample[t] =>
    st.value :: st.things    
}   

子类化是Scala中用于暂时隐藏构造时存在的信息的一种通用技术。