相关疑难解决方法(0)

Scala:什么是TypeTag以及如何使用它?

我所知道的TypeTags就是他们以某种方式取代了Manifest.互联网上的信息很少,并没有让我对这个主题有很好的认识.

所以,如果有人在TypeTag上分享了一些有用的资料,包括例子和流行的用例,我会很高兴.我们也欢迎详细的解答和解释.

types scala reification scala-2.10

355
推荐指数
1
解决办法
7万
查看次数

Scala相当于Java java.lang.Class <T> Object

最好通过一个例子来解释这个问题:

在Java中,对于JPA EntityManager,我可以执行以下操作(Account是我的Entity类):

Account result = manager.find(Account.class, primaryKey);
Run Code Online (Sandbox Code Playgroud)

在Scala中,我天真的尝试是:

val result = manager.find(Account.class, primaryKey)
Run Code Online (Sandbox Code Playgroud)

但是当我尝试Account.class在Scala中使用时,似乎不喜欢这个.如何在Scala中为Account类指定java.lang.Class对象?

java scala class

181
推荐指数
2
解决办法
9万
查看次数

Scala是否有可能在不更改JVM的情况下使用具体化的泛型?

我最近开始学习Scala并且很失望(但并不感到惊讶)他们的泛型也是通过类型擦除来实现的.

我的问题是,Scala是否有可能使用具体的泛型,或者JVM是否需要以某种方式进行更改?如果确实需要更改JVM,究竟需要更改什么?

java generics jvm scala

28
推荐指数
2
解决办法
2497
查看次数

如何在Scala中对泛型类型进行模式匹配?

我们假设我们有一个泛型类Container:

case class Container[+A](value: A)
Run Code Online (Sandbox Code Playgroud)

然后,我们希望模式匹配一个Container有Double和Container的Any:

val double = Container(3.3)  
var container: Container[Any] = double
Run Code Online (Sandbox Code Playgroud)

为此,我们通常会写:

container match {  
  case c: Container[String] => println(c.value.toUpperCase)
  case c: Container[Double] => println(math.sqrt(c.value))  
  case _ => println("_")  
}
Run Code Online (Sandbox Code Playgroud)

但是,编译器会给出两个警告,前两个案例各一个.例如,第一个警告说:"类型模式容器[String]中的非变量类型参数字符串未被选中,因为它被擦除".由于擦除,在运行期间不可能区分不同类型的容器并且第一个捕获物将匹配.因此,类型的容器Container[Double]将与捕获Container[String]对象的第一个案例匹配,因此toUpperCase将在a上调用方法,Double并且java.lang.ClassCastException将抛出a.

如何匹配Container特定类型的参数化?

scala pattern-matching type-erasure

26
推荐指数
4
解决办法
2万
查看次数

如何手动创建TypeTag?

我有兴趣手动创建一个TypeTag(从2.10M5开始):

object X {
  import reflect.runtime.universe._
  def tt[A : TypeTag](a: A) = typeTag[A] // how to do this manually?
  val t = tt(List("")(_))
}
Run Code Online (Sandbox Code Playgroud)

scalac -Xprint:typer <file>.scala 结果是

package <empty> {
  object X extends scala.AnyRef {
    def <init>(): X.type = {
      X.super.<init>();
      ()
    };
    import scala.reflect.runtime.`package`.universe._;
    def tt[A >: Nothing <: Any](a: A)(implicit evidence$1: reflect.runtime.universe.TypeTag[A]): reflect.runtime.universe.TypeTag[A] = scala.reflect.runtime.`package`.universe.typeTag[A](evidence$1);
    private[this] val t: reflect.runtime.universe.TypeTag[Int => String] = X.this.tt[Int => String](((x$1: Int) => immutable.this.List.apply[String]("").apply(x$1)))({
      val $u: reflect.runtime.universe.type = scala.this.reflect.runtime.`package`.universe;
      val $m: $u.Mirror = …
Run Code Online (Sandbox Code Playgroud)

scala

11
推荐指数
4
解决办法
4304
查看次数

为什么Scala在第一种情况下警告类型擦除而不是第二种情况?

我有两个函数(不是这些函数自原版以来都已编辑过 - 下面的一些答案是对原始函数的响应,它们返回了一系列的()):

def foo1[A](ls: Iterable[A]) : Iterator[A] =
    for (List(a, b) <- ls sliding 2) yield a

def foo2[A](ls: Iterable[A]) : Iterator[A] =
    for (a::b::Nil <- ls sliding 2) yield a
Run Code Online (Sandbox Code Playgroud)

我天真地认为是相同的.但是斯卡拉只对第一个有所减弱:

warning: non variable type-argument A in type pattern List[A]
is unchecked since it is eliminated by erasure
Run Code Online (Sandbox Code Playgroud)

我想我理解为什么它会给第一个错误:Scala认为我正在尝试使用该类型作为模式的条件,即List[B](_, _)如果B不从A继承,则匹配应该失败,除了这可以之所以发生,是因为在这两种情况下都会删除类型.

所以有两个问题:

1)为什么第二个不给出同样的警告?

2)是否有可能说服Scala在编译时实际知道该类型,因此不可能无法匹配?

编辑:我认为这回答了我的第一个问题.但我仍然对第二个感到好奇.

编辑:agilesteel在评论中提到

for (List(a, b) <- List(1,2,3,4) sliding 2) yield ()
Run Code Online (Sandbox Code Playgroud)

没有警告.这有什么不同foo1(不应该[Int]参数被删除与[A]参数相同)?

scala pattern-matching type-erasure

10
推荐指数
1
解决办法
690
查看次数

如何获得泛型类型的实际类型?

有一个泛型类:

class Action[T]
Run Code Online (Sandbox Code Playgroud)

创建它的一些实例,放入一个列表:

val list = List(new Action[String], new Action[Int])
Run Code Online (Sandbox Code Playgroud)

迭代它,以及如何获得实例的实际类型?

list foreach { action =>
     // how do I know the action is for a String or an Int?
}
Run Code Online (Sandbox Code Playgroud)

generics scala

9
推荐指数
1
解决办法
9124
查看次数

Scala的清单有哪些局限性?

Manifest由于JVM缺乏具体的泛型,Scala 是一种解决某些类型擦除问题的方法.

在其他几个问题中讨论了它们; 这里有几个:

其中一条评论提到"此功能是实验性的,有些情况下它不起作用.不过,它还有很长的路要走."(Daniel Sobral)

Manifest方法崩溃的原因是什么?为什么?

generics scala manifest reification

7
推荐指数
1
解决办法
507
查看次数

使用scala 2.10反射的类型参数的运行时解析

给定一个类型声明,我能够解析类型参数.

scala> reflect.runtime.universe.typeOf[List[Int]] match {case x:TypeRef => x.args}
res10: List[reflect.runtime.universe.Type] = List(Int)
Run Code Online (Sandbox Code Playgroud)

对于运行时值,相同的方法不起作用.

scala> reflect.runtime.currentMirror.reflect(List(42)).symbol.toType match {case x:TypeRef => x.args}
res11: List[reflect.runtime.universe.Type] = List(B)
Run Code Online (Sandbox Code Playgroud)

有没有办法克服反射值的类型擦除?

reflection scala type-erasure scala-2.10

7
推荐指数
1
解决办法
2299
查看次数

Scala与Haskell中List [T]和Set [T]上的模式匹配:类型擦除的效果

Haskell相当于下面的代码会产生正确的答案吗?

可以修复此Scala代码以生成正确的答案吗?如果有,怎么样?

object TypeErasurePatternMatchQuestion extends App {
  val li=List(1,2,3)
  val ls=List("1","2","3")
  val si=Set(1,2,3)
  val ss=Set("1","2","3")
  def whatIsIt(o:Any)=o match{
    case o:List[Int]    => "List[Int]"
    case o:List[String] => "List[String]"
    case o:Set[Int]     => "Set[Int]"
    case o:Set[String]     => "Set[String]"
  }

  println(whatIsIt(li))
  println(whatIsIt(ls))
  println(whatIsIt(si))
  println(whatIsIt(ss))

}
Run Code Online (Sandbox Code Playgroud)

打印:

List[Int]
List[Int]
Set[Int]
Set[Int]
Run Code Online (Sandbox Code Playgroud)

但我希望它能打印出来:

List[Int]
List[String]
Set[Int]
Set[String]
Run Code Online (Sandbox Code Playgroud)

haskell scala pattern-matching type-erasure erasure

7
推荐指数
2
解决办法
433
查看次数