2012-03-07 73 views
14

我有两个对象,ObjectA和ObjectB,都与一个方法update()。我想写一个接受ObjectA或ObjectB(但没有其他类型)的函数。从概念上讲,这就是我想要做的事:接受多种类型的参数在斯卡拉

def doSomething[T <: ObjectA | T <: ObjectB](obj: T) = { 
    obj.update 
} 

我知道有其他的方法来解决这个问题(例如,update()方法的结构类型,公共基类等),但我的问题是有可能在Scala中这样做,如果是这样的话,语法是什么?这叫做什么?

+0

你会怎样想到这个工作?如果编译器不知道它是什么类型,那么编译器会知道'T'有什么方法?如果你的意思是确保你的班级有'update',那么这就是结构类型的用途。 – dhg 2012-03-08 00:09:23

+4

可能的重复[是否Scala有“类型分离”(联合类型)?](http://stackoverflow.com/questions/3508077/does-scala-have-type-disjunction-union-types)。接受的答案和下一个排名最高的指向我的unboxed union编码直接解决了这个问题。 – 2012-03-08 00:28:10

+0

@dhg,如果ObjectA和ObjectB都有一个方法update(),并且type T扩展了这些类中的一个,它可以知道类型T有一个update()方法。 – 2012-03-08 06:28:19

回答

15

在斯卡拉,有一种类型可以做出不相交的联合。 基本上,你会做这样的事情:

def doSomething(obj: Either[ObjectA, ObjectB]) { 
    obj.fold(fa, fb) 
} 

结帐http://www.scala-lang.org/api/current/scala/Either.html

+1

如果你想把它们当作一个,你还可以使用结构类型:obj.fold [{def update:Unit}](identity,identity).update' – 2012-03-08 00:17:49

+1

我不知道fa或fb来自哪里你的例子或你为什么要在obj上调用fold(),但似乎是最接近,最干净的方式来做到这一点。谢谢。 – 2012-03-08 06:30:38

+0

@Bigwheels它会知道你的问题的上下文,因为我可能是错的,但它并没有真正地使同一个函数应用于两个可能的对象的工会。基本上,fa和fb是您在ObjectA或ObjectB上适用的闭包。我没有在我的例子中定义它们。你应该检查Miles Sabin对没有使用任何工会的问题的评论,但这是非常技术性的黑客行为。 – blouerat 2012-03-10 16:34:05