2015-01-12 48 views
4

Scala中的界限允许更精确地控制Scala中的类型,例如参数类型。 例如实施“排除”超类型的下界

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

上述允许一个函数来接受参数是子类型的字符串的,也

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

上述允许上的设置和下限,使得S是一个子B类型和A超类型。

我的问题是(我认为边界是包含的)是否可以设置参数类型,以便参数是一个超类型的字符串,但不包括一些超类型的下界(在这种情况下字符串)说类型任何。

UPDATE

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的呼叫应该产生非法参数异常。

回答

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只能与类型为S其中隐含Helper[S]可以解决被调用。 stringSubtype为任何S >: String提供Helper[S]。但对于Any,这两个和any适用和两个implicits冲突,所以它是不可能的(除非明确地通过一个或另一个)呼吁foo[Any]

更新:看起来anystringSubtype更高优先级,所以它解决了foo[Any]。而不是确切地说明这是为什么,最简单的解决方法是定义any2

+0

感谢您的回答,我尝试过使用它,但我无法达到预期的效果。请看看我添加到问题中的更新。 –

+0

只是评论说,答案的更新似乎解决了问题中的更新:)。我会注意到,为什么'any2'仍然是scala 2.12.2(以及dotty:https://scastie.scala-lang.org/bbarker/VRGskOyrRyaRKWIOeJ8FUA/1)的秘密。 – bbarker