2015-01-12 47 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