简介:
...
TypeTag[T]封装某些编译时类型的运行时类型表示T....
...TypeTags的总是由编译器生成....... [1]
TypeTags位于scala.reflect.**包装中.另一个SO回答提到使用java反射会在应用程序中产生运行时性能开销.
问题:s,s和s在运行时使用java反射的
程度如何?它们是在编译时生成的,但它们在使用时是否会导致运行时性能开销?TypeTagClassTagWeakTypeTag
示例:
def isOfType[A : ClassTag : TypeTag, E : ClassTag : TypeTag](actual: A, expected: E): Boolean = {
actual match {
case _ : E if typeOf[A] =:= typeOf[E] => true
case _ => false
}
}
assert( isOfType(List.empty[Int], List.empty[Int]))
assert(!isOfType(List.empty[String], List.empty[Int]))
Run Code Online (Sandbox Code Playgroud)
虽然标签是在编译时生成的,但我可以在运行时感受到延迟.类型比较是否使用了引擎盖下不那么高效的java反射?
我需要更新(检索并增加)绑定到地图中两个键的两个不同值.这两个键有时会重合.我现在有以下代码:
// val map: Map[Int, Int]
// val key1, key2: Int
if (key1 == key2) {
tailRecFunction(someArg, map
+ Tuple2(key1, 2 + map.getOrElse(key1, 0)))
} else {
tailRecFunction(someArg, map
+ Tuple2(key1, 1 + map.getOrElse(key1, 0))
+ Tuple2(key2, 1 + map.getOrElse(key2, 0)))
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,如果您使用else块时key1 == key2,则值key1 == key2将会错误地增加1而不是2---第二个元组错误地更新原始值,而不是第一个元组应用的值.
是否有更清晰的方式来写这个?
给定一个简单的类层次结构
abstract class Base {}
class A extends Base {}
class B extends Base {}
Run Code Online (Sandbox Code Playgroud)
和一个类型类
trait Show[T] {
def show(obj: T): String
}
Run Code Online (Sandbox Code Playgroud)
使用重载实现
class ShowBase extends Show[Base] {
override def show(obj: Base): String = "Base"
}
object ShowA extends ShowBase {
def show(obj: A): String = "A"
}
object ShowB extends ShowBase {
def show(obj: B): String = "B"
}
Run Code Online (Sandbox Code Playgroud)
执行以下测试用例时
Seq((new A(), ShowA), (new B(), ShowB)).foreach {
case (obj, showImpl) => println(showImpl.show(obj), obj.getClass.getSimpleName)
}
Run Code Online (Sandbox Code Playgroud)
应该产生(A,A) …
假设我需要不同的输出,具体取决于函数的多态参数的类型.我的初始尝试失败了一些神秘的错误消息:
choice :: a -> Int
choice (_ :: Int) = 0
choice (_ :: String) = 1
choice _ = 2
Run Code Online (Sandbox Code Playgroud)
但是,我们可以通过将所需类型包装在不同的数据构造函数中并在模式匹配中使用它们来轻松解决这个问题:
data Choice a = IntChoice Int | StringChoice String | OtherChoice a
choice :: Choice a -> Int
choice (IntChoice _) = 0
choice (StringChoice _) = 1
choice (OtherChoice _) = 2
Run Code Online (Sandbox Code Playgroud)
问题:你知道如何绕过这个吗?Haskell2010,GHC或任何扩展中是否有一个功能允许我使用第一个变体(或类似的东西)?