簡體   English   中英

Scala類型系統和繼承

[英]Scala type system and inheritance

采取以下Scala代碼:

import scala.collection.mutable.HashMap

class father[T,K:Numeric] extends HashMap[T,K]
class sonA[T] extends father[T, Long]
class sonB[T] extends father[T, Double]

def func_sonA[T](x: List[T]) = {
    // code
    new sonA[T]
}

def func_sonB[T](x: List[T]) = {
    // code
    new sonB[T]
}

val strList = List("one", "two", "three", "four")
val intList = List(1,2,3,4)
val both:List[List[Any]] = List(strList, intList)

val mapped = both.map(x =>
    x match {
        case i:List[String] => func_sonA(i)
        case i:List[Int] => func_sonB(i)
    }
)

mapped的類型為: List[father[_ >: String with Int, _ >: Long with Double : AnyVal]]

_>:到底是什么意思?

String with Int背后的想法是什么,它有什么用? 似乎它可以無限期地增長( String with Int with Double With Long with... )。

如何在不丟失類型信息的情況下將mapped的類型指定為List[father]List[father[Any, Any]]

我很難找到答案,因為短語_>:搜索結果不是很相關。


編輯:

為了說明造成此問題的實際問題,我想使用帶有List[father[Any, Any]]輸入的函數,但無法傳遞mapped 我收到類型不匹配錯誤。

功能:

def bar(x: List[father[Any, Any]]) = {
    println(x)
}
bar(mapped)

錯誤:

Error:(52, 9) type mismatch;
 found   : List[father[_ >: String with Int, _ >: Long with Double <: AnyVal]]
 required: List[father[Any,Any]]
    bar(mapped)
        ^

_ >: String with Int基本上意味着該類型是StringInt List[String]情況下,您會得到一個sonA[String] ,因此在此情況下會返回一個father[String, Long] ;在List[Int]情況下,您將分別sonB[Int]和一個father[Int,Double]所以與father在一起, father的第一種類型為StringInt ,第二種類型為LongDouble

關於其他問題:

如何在不丟失類型信息的情況下將映射的類型指定為List[father]List[father[Any, Any]]

你為什么要那樣? 當前類型實際上比List[father]List[father[Any,Any]].更具體List[father[Any,Any]].

編輯

好吧,我知道你想要什么。

基本上,您想要實現的目標是:

val mapped: List[father[Any,Any]] = both.map(x =>
  x match {
    case i:List[String] => func_sonA(i)
    case i:List[Int] => func_sonB(i)
  }
)

這里的問題是,目前

class father[T,K] extends HashMap[T,K]

Scala編譯器不知道例如father[String,Long]應該是father[Any,Any]的子類型(這不會自動由於StringLongAny子類型而導致)。 因此,要告訴Scala上面的方法適用,您需要在兩個類型參數中使father類協變:

class father[+T,+K] 

這樣做的問題是,您正在擴展HashMap[T,K] 但是此類僅在第一類型參數T是協變的,而在K不是。

因此,此代碼實際上有效,但未擴展HashMap

class father[+T,+K]
class sonA[T] extends father[T, Long]
class sonB[T] extends father[T, Double]

def func_sonA[T](x: List[T]) = {
  // code
  new sonA[T]
}

def func_sonB[T](x: List[T]) = {
  // code
  new sonB[T]
}

val strList = List("one", "two", "three", "four")
val intList = List(1,2,3,4)
val both = List(strList, intList)

val mapped: List[father[Any,Any]] = both.map(x =>
  x match {
    case i:List[String] => func_sonA(i)
    case i:List[Int] => func_sonB(i)
  }
)

def bar(x: List[father[Any, Any]]) = {
  println(x)
}
bar(mapped)

有關協方差的更多信息,請點擊這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM