多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > Scala之TypeTags and Manifests

Scala之TypeTags and Manifests

來源:程序員人生   發布時間:2016-11-03 08:45:35 閱讀次數:2538次

注:本文為譯文,原文是Scala官方文檔中的1篇,這里翻譯出來作為本系列的1篇文章。原文鏈接: http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html。 本文原文出處: http://blog.csdn.net/bluishglc/article/details/52596696 嚴禁任何情勢的轉載,否則將拜托CSDN官方保護權益!

  • 獲得1個TypeTag
    • 通過typeTagclassTag或weakTypeTag方法
    • 使用TypeTagTClassTagT或WeakTypeTagT的1個隱式參數
    • 使用類型參數的Context Bound
  • WeakTypeTags
  • TypeTags和Manifests

猶如所有其他的JVM語言,Scala(在范型中)的類型信息在編譯期都被擦除,這意味著如果你在運行時去檢測1些實例的類型,你可能沒法獲得全部的類型信息,即便Scala的編譯器在編譯時期都知道這些信息。

像scala.reflect.Manifest1樣, TypeTags可以被認為是攜帶了編譯期全部類型信息到運行期的對象,例如,TypeTag[T]封裝了在編譯時期肯定的T的實際類型信息,而這些信息可以在運行時期使用(為表述更清晰,本句翻譯在原文基礎上做了調劑),你要記住,TypeTags可以視作Scala 2.10之前的Manifest類的1個更加豐富的替換者,它完全和Scala的反射系統繼承在了1起。

Scala有3種不同類型的TypeTags

  1. scala.reflect.api.TypeTags#TypeTag,Scala類型的全類型描寫符,例如,TypeTag[List[String]]包括了所有的類型信息,也就是scala.List[String](譯者注:也就是除List類本身,它的范型String類型也被保存并可以獲得)。
  2. scala.reflect.ClassTag,Scala類型的部份類型描寫符,例如,ClassTag[List[String]]只包括被擦除的的類型信息,也就是scala.collection.immutable.List(譯者注:也就是只有List類本身,它的類型參數String是不會被保存的)。ClassTag只提供了訪問1個類型的運行時的類型信息,類似于scala.reflect.ClassManifest。
  3. scala.reflect.api.TypeTags#WeakTypeTag,抽象類類型的描寫符(參考后文)。

獲得1個TypeTag

猶如Manifest,TypeTag總是由編譯器生成的,可以通過3種方式獲得。

通過typeTag,classTag或weakTypeTag方法

你可以通過typeTag方法直接獲得某個特定類型的TypeTag,typeTag方法在Universe。

例如, 獲得Int型的1個TypeTag:

import scala.reflect.runtime.universe._ val tt = typeTag[Int]

或獲得String型的1個ClassTag:

import scala.reflect._ val ct = classTag[String]

這些方法基于給定的類型參數T構建了TypeTag[T] 或ClassTag[T]的實例(譯者注:在編譯期由編譯器自動完成)。

使用TypeTag[T],ClassTag[T]或WeakTypeTag[T]的1個隱式參數

像Manifest1樣,你實際上可以要求編譯器去生成1個TypeTag, 這可以通過指定1個TypeTag[T]的隱式的“跡象”(evidence)參數來實現。如果編譯器在編譯期間沒能找到匹配的隱式值,編譯器就會自動創建1個TypeTag[T]的實例(譯者注:固然,這時候類型T已肯定)。

注意:在方法和類上使用TypeTag[T],ClassTag[T]或WeakTypeTag[T]的1個隱式參數的做法是很常見的。

例如,我們可以寫1個接受任何類型做參數的方法,然后通過TypeTag打印這個參數的類型信息:

import scala.reflect.runtime.universe._ def paramInfo[T](x: T)(implicit tag: TypeTag[T]): Unit = { val targs = tag.tpe match { case TypeRef(_, _, args) => args } println(s"type of $x has type arguments $targs") }

在這里,我們寫了1個范型方法paramInfo,同時提供了1個隱式參數(implicit tag: TypeTag[T])。然后我們就能夠直接獲得類型信息(TypeTag的tpe方法返回的是T的Type實例)。

(譯者注:上述方法的意圖是:如果T是援用類型(TypeRef),獲得它的類型參數列表。)

我們可以這樣使用我們的paramInfo方法。

scala> paramInfo(42) type of 42 has type arguments List() scala> paramInfo(List(1, 2)) type of List(1, 2) has type arguments List(Int)

(譯者注:targs 本身是1個List,42是簡單類型,沒有類型參數,所以是1個空的List,List(1, 2)明顯是1個List[Int],所以它的類型參數是Int)

使用類型參數的Context Bound

1種更加簡單地實現上述目標的做法是使用1個類型參數的Context Bound。不同于提供1個獨立的隱式參數,你可以像下面這樣把TypeTag簡單的加到類型參數列表中:

def myMethod[T: TypeTag] = ...

基于給定的上下文邊界[T: TypeTag],編譯器會簡單地生成1個TypeTag[T]的隱式參數,然后把方法重寫成像前1個帶隱式參數的例子那樣。

上面使用上下文邊界的例子會被(編譯器)重寫為:

import scala.reflect.runtime.universe._ def paramInfo[T: TypeTag](x: T): Unit = { val targs = typeOf[T] match { case TypeRef(_, _, args) => args } println(s"type of $x has type arguments $targs") } scala> paramInfo(42) type of 42 has type arguments List() scala> paramInfo(List(1, 2)) type of List(1, 2) has type arguments List(Int)

WeakTypeTags

WeakTypeTag[T]泛化了TypeTag[T]。不像1個常規的TypeTag,它的類型描寫組件可以指向類型參數或抽象類型,但是,WeakTypeTag[T]總是盡量的具體化。比如,如果被援用類型參數或抽象類型的類型標簽是可用的,它們通常會被嵌入到WeakTypeTag[T]的具體類型中去。讓我們繼續上面的例子:

import scala.reflect.runtime.universe._ def weakParamInfo[T](x: T)(implicit tag: WeakTypeTag[T]): Unit = { val targs = tag.tpe match { case TypeRef(_, _, args) => args } println(s"type of $x has type arguments $targs") } scala> def foo[T] = weakParamInfo(List[T]()) foo: [T]=> Unit scala> foo[Int] type of List() has type arguments List(T)

TypeTags和Manifests

寬泛地說,TypeTags相當于2.10版本之前的scala.reflect.Manifests是相1致的。而scala.reflect.ClassTag相當于cala.reflect.ClassManifest,scala.reflect.api.TypeTags#TypeTag最貼近scala.reflect.Manifest。其他2.10版本之前的Manifest類型就沒有對應的”Tag”類型了。

  • scala.reflect.OptManifest不再被支持,由于Tag類可以具體化到任意類型,所以它們總是可用的。
  • 沒有scala.reflect.AnyValManifest的等價物。相應地,你可以用base Tag比較它們的Tag以便找出是不是它表示的是1個primitive value class。另外,它還可以簡單的使用.tpe.typeSymbol.isPrimitiveValueClass
  • Manifest伴生對象中定義的工廠方法也沒有替換物
  • 某些 manifest 的操作如(i.e., <:<, >:> and typeArguments)都不再被支持。

在Scala 2.10里,scala.reflect.ClassManifests不再被推薦使用!scala.reflect.Manifest也將被TypeTags和ClassTag所代表的風格所取代。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 一级做a爱过程免费视频超级 | 国产成人综合亚洲欧洲色就色 | 中文字幕在线视频网 | 亚洲 中文 欧美 日韩 在线人 | 欧美精品亚洲精品 | 激情视频在线观看 | 好好的日视频www | 中文字幕福利 | 欧美日韩亚洲综合另类ac | 国产精品亚洲第五区在线 | 国产高清看片日韩欧美久久 | 欧美一区二区另类有声小说 | 成人免费在线视频网站 | jizz日本护士视频 | 免费观看性行为的视频网站 | 国产成人精品久久一区二区小说 | 亚洲综合国产 | 精品日韩欧美国产一区二区 | 99久久精品国产一区二区成人 | 午夜小视频网站 | 欧美成人国产 | 国产成人综合网亚洲欧美在线 | 久久www免费人成高清 | 国产亚洲人成在线影院 | 亚洲欧美偷拍视频 | 欧美日韩福利视频一区二区三区 | 性xxxx奶大欧美高清 | 最近中文字幕资源8 | 国产成人精品久久二区二区 | 精品久久久久久久 | 国产日韩欧美一区二区三区视频 | 欧美日韩在线看 | jizzjizz之xxxx18| 国产日韩久久 | 国产一级鲁丝片 | 国产精品99久久久久久人 | 国产亚洲精品久久久久久 | 欧美成人精品福利在线视频 | 得得啪在线 | 在线免费观看h | 2022国产男人亚洲欧美天堂 |