是否有可能在Scala中创建一个类型别名(或类似的东西),它接受两个参数并返回它们的常见超类型?换句话说,我正在尝试使用此签名找到一些东西:
type CommonSupertype[A, B] // can't be more specific
Run Code Online (Sandbox Code Playgroud)
这些都适用:(伪代码)
CommonSupertype[String, Int] = Any
CommonSupertype[JButton, JPanel] = JComponent
Run Code Online (Sandbox Code Playgroud)
等等
我自己无法找到它,但我不能使用其他替代参数,因为我必须遵循预先指定的接口.
(不是一个完整的解决方案,但可能提供一些想法)
Scala 的一个令人印象深刻的功能是,当将橙子附加到苹果列表时,它能够返回水果列表。值很好,正是因为您可以推断泛型类型。
import scala.reflect.Manifest
def CommonSuperType[A, B >: A : Manifest](a:A, b:B) = manifest[B]
Run Code Online (Sandbox Code Playgroud)
它有效(有点):
scala> CommonSuperType(new JButton, new JPanel)
res42: Manifest[javax.swing.JComponent with javax.accessibility.Accessible] = javax.swing.JComponent with javax.accessibility.Accessible
Run Code Online (Sandbox Code Playgroud)
下一步是将这个技巧提升到更高种类的类型(未经测试)。
半生不熟的解决方案包括从类型创建值(参见这个答案):
class CommonSuper[A:Manifest, B:Manifest] {
def make[T:Manifest] = manifest[T].erasure.newInstance.asInstanceOf[T]
val instanceA = make[A]
val instanceB = make[B]
def getType = CommonSuperType(instanceA, instanceB)
}
Run Code Online (Sandbox Code Playgroud)
但我陷入了这种不直观的不一致:
scala> val test = new CommonSuper[JButton, JPanel]
scala> test.getType
res66: Manifest[Any] = Any
scala> CommonSuperType(test.instanceA, test.instanceB)
res67: Manifest[javax.swing.JComponent with javax.accessibility.Accessible] = javax.swing.JComponent with javax.accessibility.Accessible
Run Code Online (Sandbox Code Playgroud)
不管怎样,虽然我喜欢这种类型的问题(关于类型的问题),但这里闻起来像XY Problem。