[英]Why Scala fail to recognize Null type as a subtype of T in generic function type parameter inference?
[英]Scala type inference for both a generic type and it's type parameter - why doesn't it work?
如果我要說出關於scala的最令人煩惱的事情,那么對於以下代碼:
trait G[+T]
class H[+T] extends G[T]
def f[A<:G[X], X<:Int](g :A)
val g :H[Int]
f(g)
編譯器推斷最后一次調用f [H [Int],Nothing]的類型,並在我面前因為自己的愚蠢而抱怨。
然而,知道scala,它實際上比我更清楚。 它背后的原因是什么? 由於G和H對於T都是協變的,對於任何類型S, S <: G[X] with H[_] <=> S<: H[X]
。這一個缺點使我設計了一切,避免必須指定明確的類型 - 它可能在這里看起來沒什么,但是當名稱變成'真實'長度並且幾乎任何方法都是通用的,並且經常處理兩種泛型類型時,事實證明大多數代碼都是類型聲明。
編輯:上面的案例在下面由Noah解決,但是當派生類與基類不同時,如下所示?
trait G[+X]
class H[+X, Y] extends G[X]
class F extends G[Int]
def f[A<:G[X], X<:Int](g :A) = g
val h: H[Int, String] = ???
val g :F = ???
f(g)
f(h)
如果你讓A
坐式paramater A[_]
我認為你可以得到Scala編譯器同意你的觀點,而不是僅僅讓一切Nothing
:
def f[A[_] <: G[_], X <: Int](g: A[X])
作為旁注,我通常會在我遇到類型問題時查看scalaz
源代碼,因為他們通常會遇到它並盡可能地解決它。
UPDATE
我上面提供的方法仍然適用於給出的附加約束:
trait G[+X]
class H[+X, Y] extends G[X]
class F extends G[Int]
class I extends G[String]
def f[A[_] <: G[_], X <: Int](g: A[X]) = g
val h: H[Int, String] = new H[Int, String]
val g: F = new F
val i:I = new I
f(g) //works
f(h) //works
f(i) // should fail and does fail
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.