Scala生活中的一个可悲事实是,如果你实例化一个List [Int],你可以验证你的实例是一个List,你可以验证它的任何单个元素是一个Int,但不是它是一个List [ Int],可以很容易地验证:
scala> List(1,2,3) match {
| case l : List[String] => println("A list of strings?!")
| case _ => println("Ok")
| }
warning: there were unchecked warnings; re-run with -unchecked for details
A list of strings?!
Run Code Online (Sandbox Code Playgroud)
-unchecked选项将责任直接归咎于类型擦除:
scala> List(1,2,3) match {
| case l : List[String] => println("A list of strings?!")
| case _ => println("Ok")
| }
<console>:6: warning: non variable type-argument String in type pattern is unchecked since it is eliminated by erasure
case l …Run Code Online (Sandbox Code Playgroud) 从Scala 2.7.2开始,有一些叫做ManifestJava类型擦除的解决方法.但是,如何Manifest确切地工作以及为什么/何时需要使用它?
Jorge Ortiz 的博客文章Manifests:Reified Types解释了其中的一些内容,但它没有解释如何将它与上下文界限一起使用.
那么ClassManifest,有什么区别Manifest?
我有一些代码(一个更大的程序的一部分,不能轻易地包含在这里),它有关于类型擦除的一些警告; 我怀疑我可以通过使用清单解决这些问题,但我不确定如何解决.
我听说Dynamic在某种程度上可以在Scala中进行动态类型化.但我无法想象这可能是什么样子或它是如何工作的.
我发现一个人可以继承特质 Dynamic
class DynImpl extends Dynamic
Run Code Online (Sandbox Code Playgroud)
该API称,可以使用这样的:
foo.method("blah")~~> foo.applyDynamic("method")("blah")
但是当我尝试它时它不起作用:
scala> (new DynImpl).method("blah")
<console>:17: error: value applyDynamic is not a member of DynImpl
error after rewriting to new DynImpl().<applyDynamic: error>("method")
possible cause: maybe a wrong Dynamic method signature?
(new DynImpl).method("blah")
^
Run Code Online (Sandbox Code Playgroud)
这是完全合乎逻辑的,因为在查看来源之后,事实证明这个特征是完全空的.没有applyDynamic定义方法,我无法想象如何自己实现它.
有人能告诉我我需要做些什么才能让它发挥作用吗?
我一直在阅读与新反射api一起出现的新TypeTag.似乎Manifest应该被这个新概念所取代.任何人都可以发布一些代码示例来展示好处吗?
一些参考:
我有scala函数,如下所示:
现在,根据T的类型(在我的情况下,它可以是Double,Boolean和LocalDate),我需要应用函数ob.像这样的东西(我知道代码没有任何意义,但我想传达我的意思):
def X[T](ob: Observable[T]): Observable[T] = {
//code
T match {
case Double => DoSomething1(ob:Observable[Double]):Observable[Double]
case Boolean => DoSomething2(ob:Observable[Boolean]):Observable[Boolean]
case LocalDate => DoSomething3(ob:Observable[LocalDate]):Observable[LocalDate]
}
}
Run Code Online (Sandbox Code Playgroud)
考虑到Scala的Erasure属性,可以用某种方式反射来完成工作吗?它甚至可能吗?
让我们说一个班级:
case class Foo(id: Int, name: String, note: Option[String] = None)
Run Code Online (Sandbox Code Playgroud)
自动生成的伴随对象中的构造函数和apply方法都有三个参数.通过反射查看时,标记了第三个参数(注释):
p.isParamWithDefault = true
Run Code Online (Sandbox Code Playgroud)
此外,通过检查,我可以找到在伴随对象中生成值的方法:
method <init>$default$3
Run Code Online (Sandbox Code Playgroud)
和
method apply$default$3
Run Code Online (Sandbox Code Playgroud)
哪两个都有:
m.isParamWithDefault = true
Run Code Online (Sandbox Code Playgroud)
但是,我无法在TermSymbol上找到任何关于notes参数的内容,它实际上指向了正确的方法来获取默认值,也没有找到上述MethodSymbols中指向参数的TermSymbol的任何内容.
是否有直接的方法将参数的TermSymbol与生成其默认值的方法相关联?或者我是否需要做一些像检查伴侣对象上的方法名称一样的事情?
我对这里的case类构造函数示例和常规方法感兴趣.
我正在尝试使用宏实现自定义字符串插值方法,我需要一些关于使用API的指导.
这是我想要做的:
/** expected
* LocatedPieces(List(("\nHello ", Place("world"), Position()),
("\nHow are you, ", Name("Eric"), Position(...)))
*/
val locatedPieces: LocatedPieces =
s2"""
Hello $place
How are you, $name
"""
val place: Piece = Place("world")
val name: Piece = Name("Eric")
trait Piece
case class Place(p: String) extends Piece
case class Name(n: String) extends Piece
/** sequence of each interpolated Piece object with:
* the preceding text and its location
*/
case class LocatedPieces(located: Seq[(String, Piece, Position)])
implicit class s2pieces(sc: StringContext) {
def …Run Code Online (Sandbox Code Playgroud) 我有兴趣手动创建一个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) 我正在玩Scalas的新宏,并从akshaal中找到了这个要点.因为它接缝我不太明白.给出以下特征(fieldsMacro或多或少与akshaal示例相同)
case class Field[I <: AnyRef](name: String, get: I => Any)
type Fields[I <: AnyRef] = List[Field[I]]
trait FieldAccess {
import FieldMacors._
import Field._
import language.experimental.macros
def fields[T <: AnyRef]: Fields[T] = macro fieldsMacro[T]
def field[T <: AnyRef](name: String): Fields[T] = fields[T].headOption <-- does not work!
^
}
object FieldMacors {
import language.experimental.macros
import Field._
def fields[T <: AnyRef]: Fields[T] = macro fieldsMacro[T]
/**
* Get a list of fiels
*/
def fieldsMacro[T <: AnyRef: c.TypeTag](c: …Run Code Online (Sandbox Code Playgroud) 给定一个类型声明,我能够解析类型参数.
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)
有没有办法克服反射值的类型擦除?
scala ×10
scala-2.10 ×4
reflection ×3
type-erasure ×3
macros ×2
erasure ×1
generics ×1
manifest ×1