强制执行排除"排除"超级型

时间:2015-01-12 22:43:49

标签: scala typing type-bounds

Scala中的Bounds允许对Scala中的类型进行更细粒度的控制,例如参数类型。 例如

def foo[ S <: String ]( arg: S ): S = ...

上面允许函数接受作为String子类型的参数,也是

def bar[ S >: A <: B ]( arg: S ): S = ...

以上允许设置上限和下限,以便S是B的子类型和A的超类型。

我的问题是(我假设边界是包容性的)是否可以设置参数类型,以便参数可以是String的超类型,但不包括下限的某些超类型(在这种情况下) String)说类型为Any。

更新

sealed trait Helper[S]
object Helper {
  implicit def stringSubtype[S >: String] = new Helper[S]{}
  implicit def any = new Helper[Any]{}
}

def foo[S: Helper](r: S): Int = 1

val arg1: String = "hi"
val arg2: Any    = "hello"

foo(arg1)
foo(arg2)

我希望用arg2调用会导致非法的参数异常。

1 个答案:

答案 0 :(得分:3)

对于更复杂的类型约束,你可以通过implicits进行类型级编程:

sealed trait Helper[S]
object Helper {
  implicit def stringSubtype[S >: String] = new Helper[S]{}
  implicit def any = new Helper[Any]{}
  implicit def any2 = new Helper[Any]{}
}

def foo[S: Helper] = ...
只能使用可以解析隐式foo的{​​{1}}类型调用

SHelper[S]为任何stringSubtype提供Helper[S]。但是对于S >: StringAnyany都适用,并且两个含义冲突,所以它不可能(除非明确传递一个或另一个)调用foo[Any]

更新:似乎any的优先级高于stringSubtype,因此已为foo[Any]解决了问题。最简单的解决方法是定义any2

,而不是弄清楚为什么会这样