在REPL中,我写出了Reflection - TypeTags和Manifests中的例子.
我WeakTypeTag和之间的区别感到困惑TypeTag.
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
Run Code Online (Sandbox Code Playgroud)
TypeTag
scala> def paramInfo[T](x: T)(implicit tag: TypeTag[T]): Unit = {
| val targs = tag.tpe match { case TypeRef(_, _, args) => args }
| println(s"type tag of $x has type arguments $targs")
| }
paramInfo: [T](x: T)(implicit tag: reflect.runtime.universe.TypeTag[T])Unit
Run Code Online (Sandbox Code Playgroud)
WeakTypeTag
scala> def weakParamInfo[T](x: T)(implicit tag: WeakTypeTag[T]): Unit = {
| val targs = tag.tpe match { case TypeRef(_, _, args) => args }
| …Run Code Online (Sandbox Code Playgroud) 请注意,这是一个社区帖子,应根据需要添加示例.如果您无法直接编辑添加示例(问题示例或解决方案)的答案,请在评论中发布带有要点(或类似内容)的链接或添加单独的答案,以便稍后进行集成.
Scala 3可能根本不包含scala.reflect.runtime(Dotty目前没有,并且计划这样做不确定).虽然适用于Scala 2和Dotty的答案可能是转换目的和立即改进性能的首选,但也欢迎Dotty特定的解决方案.
https://www.cakesolutions.net/teamblogs/ways-to-pattern-match-generic-types-in-scala
我正在尝试制作自定义异构列表和地图.虽然有使用Manifest的例子,但是Scala 2.10它们已被弃用,我应该使用TypeTags(或Classtags).在地图的情况下,似乎我可以使用(比如)元组字符串 - >(TypeTag [_ <:Any],Any)保留Any与Type的绑定.
我的问题是如何从恢复的TypeTag和未定义的T中获取,以便能够返回TypeTag.tpe的实例 - 在我所拥有的代码中
//** How do I use saved typeTag to define T here?**
如上所述,方法get中没有编译器错误,但T设置为Nothing并返回Some(Nothing).我希望我的注释掉的行能够工作:
case Some( x ) => // println( "Get 2*'pi'=" + x*2 )有一个编译器消息,"value*不是Nothing的成员".我意识到我可以更紧凑地编写,但是完成之后,我可以在我的IDE中鼠标悬停并按照一步一步进行操作.有一个相关的问题 - Scala:什么是TypeTag以及如何使用它? 但它似乎没有走"最后一英里" - 重新选择任何一个.
这该怎么做?
这是我到目前为止的代码:
import scala.reflect._
import scala.reflect.runtime.universe._
import collection.mutable.Map
object Test extends HMap {
def main( args: Array[ String ] ) {
var hmap = new HMap
hmap( "anInt" ) = 1
hmap( "pi" ) = 3.1416f
hmap( "c" ) = "hello" …Run Code Online (Sandbox Code Playgroud) object Test {
def main(args: Array[String]) {
val list: List[Double] = List(1.0, 2.0, 3.0, 4.0)
val none = None
case class Test()
val test = Test()
def f(x: Any) = x match {
case _: Some[Test] => println("_ matched")
case None => println("None matched")
}
f(list)
f(none)
f(test)
}
}
Run Code Online (Sandbox Code Playgroud)
尝试编译上面的代码会导致"擦除"编译时警告.
$>scalac Test.scala
Test.scala:11: warning: non-variable type argument Test in type pattern
Some[Test] is unchecked since it is eliminated by erasure
case _: Some[Test] => println("_ matched")
^
one warning …Run Code Online (Sandbox Code Playgroud) 我想知道,为什么这不起作用:
def example(list: List[Int]) = list match {
case Nil => println("Nil")
case List(x) => println(x)
}
example(List(11, 3, -5, 5, 889, 955, 1024))
Run Code Online (Sandbox Code Playgroud)
它说:
scala.MatchError: List(11, 3, -5, 5, 889, 955, 1024) (of class scala.collection.immutable.$colon$colon)
Run Code Online (Sandbox Code Playgroud)
我坐在一个大约10000 LoC的项目前.我必须将此项目从Scala 2.9更新到2.10.这样做得很好,但由于清单,我收到了许多弃用警告.
在使用stackoverflow和许多其他站点的搜索功能之后,我没有那么多问题.我想总结一下; 关键点是:
TypeTags和ClassTag比Manifest和ClassManifest好得多.特别是你可以使用这些作为同义词(TypeTags < - > Manifests和ClassTags < - > ClassManifest)
TypeTag比ClassTag更强大,ClassTag更受限制TypeTags.我的第一个问题:在这个项目中,manifest[T].erasure.getSimpleName经常使用这种方法.现在我不仅可以将其切换为,typeTag[T].runtimeClass.getSimpleName因为代码不会编译,但是classTag[T].runtimeClass.getSimpleName它会编译.这会影响语义吗?(注意:该方法erasure也已弃用;您必须使用该方法runtimeClass)
第二个问题: Scala 2.9中的清单类型检查是:manifest[T] <:< manifest[A].在Scala 2.10中,我会写这个typeOf[T] <:< typeOf[A].但是<:<被弃用了?!
我可以将TypeTag转换为ClassTag吗?即:如果我只使用清单进行类型检查(Nr.3)和名称提取(Nr.2):我能将每个Manifest/ClassManifest重命名为ClassTag吗?
我想得到一个List的内部类型的清单,如下所示并将其传递给另一个函数,我该怎么做?谢谢
def f(any: Any) = any match {
case x: Int => println("Int")
case a: List[_] => // get the manifest of List's inner type, and use it in the function g()
}
def g[T:Manifest](list:List[T]) = {}
Run Code Online (Sandbox Code Playgroud) 所以说我们有几个这样的类:
abstract class Throw {
def winsOver(t2: Throw): Boolean
}
class Rock extends Throw {
override def winsOver(t2: Throw): Boolean = t2 match {
case _: Scissors => true
case _ => false
}
}
class Scissors extends Throw {
override def winsOver(t2: Throw): Boolean = t2 match {
case _: Paper => true
case _ => false
}
}
class Paper extends Throw {
override def winsOver(t2: Throw): Boolean = t2 match {
case _: Rock => true
case …Run Code Online (Sandbox Code Playgroud) 有没有办法可以获得函数的字符串表示?
val f = List(1, 2, 3, 4, 66, 11).foldLeft(55)_
f是一个类型的函数((Int, Int) => Int) => Int,这将是我正在寻找的表示,但我无法在任何地方找到它.
toString当然,这个方法是我的第一次尝试,但它返回的只是<function1>.scala REPL做得对,文档也是如此.一定有办法吗?
问候.
如果我有一个接受Type参数的类,例如Seq[T],我有很多这个类的对象.我想根据类型Argument拆分它们T
例如 :
val x = List(Seq[Int](1,2,3,4,5,6,7,8,9,0),Seq[String]("a","b","c"))
x.foreach { a =>
a match{
case _ : Seq[String] => print("String")
case _ : Seq[Int] => print("Int")
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码的结果是 StringString.它只匹配类Seq而不是类型,我应该怎么做才能强制它匹配类型?
我编写了一个泛型函数来从HashMap [String,AnyVal]中获取值.此方法从名称返回一个值,但也具有确保它具有特定类型的功能:
class Context {
private var variables = HashMap[String, Any] ()
def getVariable (name: String):Any = variables(name)
def setVariable (name: String, value: Any) = variables += ((name, value))
def getVariableOfType[T <: AnyVal] (name:String):T ={
val v = variables(name)
v match {
case T => v.asInstanceOf[T]
case _ => null.asInstanceOf[T]
}
}
}
Run Code Online (Sandbox Code Playgroud)
函数getVariableOfType [T <:AnyVal]将无法编译,因为它在行情况下显示"无法解析符号T" T => v.asInstanceOf[T]
我想知道是否有可能做以下事情:
import scala.reflect.runtime.universe._
class Bar[T]
def foo[T]()(implicit ctag: reflect.ClassTag[T]) {
val clazz = classOf[Bar[ctag.runtimeClass.asInstanceOf[Class[T]]]]
}
Run Code Online (Sandbox Code Playgroud)
这里Scala编译器抱怨:
error: stable identifier required, but ctag.runtimeClass found.
Run Code Online (Sandbox Code Playgroud)
有没有办法从函数中可用的运行时类型信息中插入类型参数的类类型?