[英]Scala: constrain a class type parameter for a member function
給定具有類型參數T
A
類,我如何進一步限制T
的特定功能? 在下面的示例中,我想強制執行以下操作:僅當T
為Int
(或子類型,如果您願意)時,才能調用foo
。 即,應該編譯new A[Int]().foo()
,但不應編譯new A[Double]().foo()
。
我可以通過隱式轉換T => Int
實現我想要的結果,如foo
。 但是,這會導致不必要的方法調用-隱式找到的證據是身份函數。 而且,它看起來也不是很好...
class A[T] {
val someValue: T = ???
def foo()(implicit ev: T => Int): Int = ev(someValue)
// some ideas that don't quite work
// def bar[T2 <: Int :EqualTo[T]](t2: T2): T = t2.asInstanceOf[T]
// def bam[T2 <: T with Int](): Int = someValue.asInstanceOf[Int]
def thisOneDefinesItsOwnConstraintType[Z <: Int](z: Z): Z = z
def thisOneDoesNotNeedToConstrainT(t: T): T = someValue
}
如果不需要強制轉換,該解決方案將獲得加分:)
注意:我知道我可以在類或方法級別上定義類型約束(請參見thisOneDefinesItsOwnConstraintType
),但這thisOneDefinesItsOwnConstraintType
,因為我還有一些不需要約束類型的方法(請參見thisOneDoesNotNeedToConstrainT
)。
我看不到沒有隱式方法的方法,因為雖然您可以在類方法上施加一些約束B <: C
,但是您對B <: T
要求很難概括,因為我們不知道C
如何與任意T
幸運的是,Scala已經為此構造了<:<
類型類。 在Predef
生成的<:<[B, T]
的Predef
將提供B <: C
證據。
要限制方法參數列表中范圍內的任何抽象類型T(而不僅僅是方法自身的類型參數),只需添加類型T <:<U的隱式參數,其中U是所需的上限; 或對於下限,請使用:L <:<T,其中L是所需的下限。
例如:
class E
class F extends E
class G extends F
class A[T] {
def constrained[B <: F](b: B)(implicit ev: B <:< T): B = b
}
在這里,我們引入一個上界的F
類型參數B
所述的contrained
方法。 但是,如果你也想保證B <: T
(無需添加其他類型的參數),您可以添加隱B <:< T
scala> val a = new A[E]
a: A[E] = A@5a63f509
scala> a.constrained(new E)
<console>:15: error: inferred type arguments [E] do not conform to method constrained's type parameter bounds [B <: F]
a.constrained(new E)
^
<console>:15: error: type mismatch;
found : E
required: B
a.constrained(new E)
^
scala> a.constrained(new F)
res5: F = F@4a668b6e
scala> a.constrained(new G)
res6: G = G@4de4b452
怎么樣:
implicit class AIntOps(a: A[Int]) {
def test(x: Int) = x
}
使用該方法,測試僅對A[Int]
出現,而對其他任何A
都不可用
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.