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调用会导致非法的参数异常。
答案 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}}类型调用 S
。 Helper[S]
为任何stringSubtype
提供Helper[S]
。但是对于S >: String
,Any
和any
都适用,并且两个含义冲突,所以它不可能(除非明确传递一个或另一个)调用foo[Any]
更新:似乎any
的优先级高于stringSubtype
,因此已为foo[Any]
解决了问题。最简单的解决方法是定义any2
。