這篇文章主要為大家展示了“scala怎么匹配自定義泛型類型”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“scala怎么匹配自定義泛型類型”這篇文章吧。
創(chuàng)新互聯(lián)公司主要從事做網(wǎng)站、成都網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)崇州,10多年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792
我正在嘗試使用模式匹配來檢測基于 this answer的我自己的自定義類型的泛型類型.
作者提供的代碼按預(yù)期工作:
import scala.reflect.runtime.{universe => ru} def matchList[A: ru.TypeTag](list: List[A]) = list match { case strlist: List[String @unchecked] if ru.typeOf[A] =:= ru.typeOf[String] => println("A list of strings!") case intlist: List[Int @unchecked] if ru.typeOf[A] =:= ru.typeOf[Int] => println("A list of ints!") } matchList(List("a", "b", "c")) matchList(List(1,2,3))
正確顯示:
A list of strings! A list of ints!
現(xiàn)在基于此我試圖應(yīng)用相同的模式來檢測我的自定義類Foo的泛型類型.下面的代碼是copy-pased,除了它使用Foo而不是List:
import scala.reflect.runtime.{universe => ru} class Foo[T](val data: T) def matchFoo[A: ru.TypeTag](foo: Foo[A]) = { println("Is string = " + (ru.typeOf[A] =:= ru.typeOf[String])) println("Is int = " + (ru.typeOf[A] =:= ru.typeOf[Int])) foo match { case fooStr: Foo[String @unchecked] if ru.typeOf[A] =:= ru.typeOf[String] => println("Found String") case fooInt: Foo[Int @unchecked] if ru.typeOf[A] =:= ru.typeOf[Int] => println("Found Int") } } matchFoo(new Foo[String]("str")) println("------------") matchFoo(new Foo[Int](123))
只有這次它輸出的不是我所期望的:
Is string = trueIs int = falseFound String ------------ Is string = falseIs int = trueFound String // wth?
第二個(gè)調(diào)用matchFoo(new Foo [Int](123))如何顯示Found String?正如你所看到的,我甚至明確地印出了比賽條件,他們很好.
在線代碼:http://goo.gl/b5Ta7h
編輯:
我通過將匹配條件提取到變量中來實(shí)現(xiàn)它:
def matchFoo[A: ru.TypeTag](foo: Foo[A]) = { val isString: Boolean = ru.typeOf[A] =:= ru.typeOf[String] val isInt: Boolean = ru.typeOf[A] =:= ru.typeOf[Int] println("Is string = " + isString) println("Is int = " + isInt) foo match { case fooStr: Foo[String @unchecked] if isString => println("Found String") case fooInt: Foo[Int @unchecked] if isInt => println("Found Int")} }
在線代碼:http://goo.gl/mLxYY2
但在我看來,原始版本也應(yīng)該有效.我不認(rèn)為我在這里缺少運(yùn)算符優(yōu)先級,因?yàn)閷l件包裝到括號中也沒有幫助.
它是Scala中的錯(cuò)誤嗎?我正在使用Scala SDK v.2.11.5和JDK v.1.8.0_25.在線CodingGround使用Scala SDK v.2.10.3.
編輯2:
我已經(jīng)在Scala的bugtracker中打開了一個(gè)問題.你可以投票支持here.
這看起來非常像編譯器中的一個(gè)錯(cuò)誤,它無法解析正確的隱式(可能是@unchecked的存在?).
case fooStr: Foo[String @unchecked] if ru.typeOf[A] =:= ru.typeOf[String] => println(implicitly[TypeTag[String]]) // will print TypeTag[Int]
通過查看字節(jié)代碼,編譯器使用傳遞給方法的TypeTag($evidence).
(有限的)解決方法可能是使用ru.definitions.IntTpe:
case fooStr: Foo[Int @unchecked] if ru.typeOf[A] =:= ru.definitions.IntTpe => println("That's an Int")
以上是“scala怎么匹配自定義泛型類型”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!