简体   繁体   English

Scala中构造函数的通用参数

[英]Generic parameters for a constructor in Scala

Consider the following contrived Java example: 考虑以下设计的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;
    }

}

What I care about in this Example: 我在这个例子中关心的是:

  1. Example is not parameterized Example未参数化
  2. The constructor is paremeterized and makes sure that whatever you pass in, the list is parameterized in the same type of t 构造函数 paremeterized并确保无论您传入什么,列表都在相同类型的t参数化

(This is a contrived example, I do not really care about (2) but I really do care about having a type parameter there which is not mentioned in the definition of the class). (这是一个人为的例子,我并不关心(2)但我确实关心那里有一个类型参数,这个类参数在类的定义中没有提到)。

Now in Scala I tried the following: 现在在Scala中我尝试了以下方法:

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

  def this[T](t: T, aListOfTheseThings: List[T]) {
    this(t, aListOfTheseThings)
  }
}

...but this is not possible. ......但这是不可能的。 Apparently a type parameter is not valid in a constructor (in this ). 显然,类型参数在构造函数中无效(在this )。

Any chance of translating the above Java code into Scala? 是否有机会将上述Java代码翻译成Scala?

Maybe this help: 也许这个帮助:

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 
}

This makes private constructor of class Example . 这使得类的私有构造函数Example value and aListOfTheseThings are not accessed via Example trait (unless you make it accessible) 不能通过Example trait访问value和aListOfTheseThings (除非你可以访问它)

Nyavro's suggestion of a helper apply method is a good one. Nyavro建议使用辅助apply方法是一个很好的方法。 Another option that might be appropriate in some cases is subclassing: 在某些情况下可能适用的另一种选择是子类化:

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

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

The advantage of subclassing is that the constraint that value and things store the same type is not lost, and can be re-discovered by pattern matching: 子类化的优点是valuethings存储相同类型的约束不会丢失,并且可以通过模式匹配重新发现:

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

Subclassing is a general technique in Scala for temporarily hiding information that was present at construction time. 子类化是Scala中用于临时隐藏构造时存在的信息的一种通用技术。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM