是否可以将泛型参数限制为超类型的子集?

时间:2018-04-09 08:05:20

标签: scala

在Scala中,我可以将通用参数限制为超类型的子集吗?

sealed trait A
class X extends A
class Y extends A
class Z extends A

def myStrictFunc[T is X or Y, but not Z](o: T)
                 ----------+----------
                           |
                           Can I have this constraint in Scala ?

3 个答案:

答案 0 :(得分:1)

是的,你可以。例如,使用Shapeless

import shapeless.=:!=

sealed trait A
class X extends A
class Y extends A
class Z extends A

def myStrictFunc[T <: A](o: T)(implicit ev: T =:!= Z) = ???

否则您可以手动实施=:!=

Enforce type difference

答案 1 :(得分:1)

如果您需要排除其中一个,Dmytro Mitin的答案是一个很好的答案。另一方面,如果你需要将包含限制在少数几个中,这是一种方法。

driver = webdriver.PhantomJS(executable_path='Complete path/to/phantomjs.exe')

sealed trait A {val id: Int} class W extends A {val id = 13} class X extends A {val id = 17} class Y extends A {val id = 18} class Z extends A {val id = 21} trait Contra[-X] type Union[A,B] = { type Check[Z] = Contra[Contra[Z]] <:< Contra[Contra[A] with Contra[B]] } def myStrictFunc[T <: A : Union[X,Y]#Check](t: T): Int = t.id myStrictFunc(new X) //res0: Int = 17 myStrictFunc(new Y) //res1: Int = 18 myStrictFunc(new Z) //won't compile myStrictFunc(new W) //won't compile 类型可以扩展为3,4或更多类型,但代码有点冗长。

答案 2 :(得分:1)

使用Shapeless可能是目前最简单的方法,但是,您可能需要检查Dotty,它是下一代Scala编译器并具有built-in Union types