Scala 隐式参数与类型标签何时使用以及为什么使用
Scala遭受了类型擦除,但它还引入了类型标签,以克服类型擦除问题 有时,我们可以使用隐式参数(甚至值参数也足够)来解决我们遇到的相同问题 例如:Scala 隐式参数与类型标签何时使用以及为什么使用,scala,functional-programming,Scala,Functional Programming,Scala遭受了类型擦除,但它还引入了类型标签,以克服类型擦除问题 有时,我们可以使用隐式参数(甚至值参数也足够)来解决我们遇到的相同问题 例如: // implicit paramters def getKindName[T](implicit x: T): String = { x match { case _: People => "Mammals" case _: Sparrow => "Birds" case _:
// implicit paramters
def getKindName[T](implicit x: T): String = {
x match {
case _: People => "Mammals"
case _: Sparrow => "Birds"
case _: Shark => "Fishes"
case _: Crocodile => "Reptiles"
case _ => ???
}
}
// TypeTag
def getKindName[T: TypeTag]: String = {
typeOf[T] match {
case t if t =:= typeOf[People] => "Mammals"
case t if t =:= typeOf[Sparrow] => "Birds"
case t if t =:= typeOf[Shark] => "Fishes"
case t if t =:= typeOf[Crocodile] => "Reptiles"
case _ => ???
}
}
因此,我的问题是:
- 为什么以及何时使用类型标记和隐式参数
- 类型标记和隐式参数之间的性能差异是什么
TypeTag
s几乎总是用作隐式参数。如果您不知道,getKindName[t:TypeTag]
表示getKindName[t](隐式标记:TypeTag[t])
。
例外情况是,当您将作为隐式参数获得的TypeTag
存储在某处时。因此,“隐式参数vsTypeTag
”一开始就没有意义implicit val x: Animal = new People
getKindName1[Sparrow] // returns "Mammals"
或者如果没有定义任何额外的隐式,getKindName1[Sparrow]
将根本无法编译(并且不清楚为什么会有隐式Sparrow
)你把苹果比作桔子。隐式参数允许将参数隐式传递给方法。TypeTag在运行时提供类型信息以避免类型擦除。是的,我理解你的意思。但是我想知道我是否可以使用隐式参数来消除类型擦除,为什么我应该使用TypeTag?Scala不“使用”类型擦除。更像是因为它是一种JVM语言而遭受类型擦除。隐式的使用对类型擦除没有影响。这两者是不相关的。@LeylaLee如果您确实需要关于
T
真正是什么类型的信息,那么就使用type标记。由于JVM在编译时擦除泛型类型,Scala会向您提供类型信息,以便您可以提出此类问题。@jwvh是的,您是对的,它会遭受类型擦除而不是“使用”类型擦除,并且隐式不会影响类型擦除。但这不是我要问的,我的意思是,在某些情况下,隐式标记可以用来代替TypeTag,为什么使用TypeTag以及使用TypeTag的好处是什么?谢谢你的回答。但我不认为有一些观点我不同意。我不认为它会返回“哺乳动物”,它应该返回类似于找不到参数x的隐式值的东西在这个例子中,它根据它接收的动物类返回一个字符串,但是,由于类型擦除,它将丢失类型信息,不是吗?我认为隐式参数可以保留类型信息。所以我想知道,如果隐式参数已经足够“它根据接收到的动物类返回一个字符串”,为什么要使用type标记?否。它根据接收到的值返回。如果Sparrow
扩展了Animal
,则在搜索隐式Sparrow
时将找到x
,匹配项将返回“哺乳类”
,因为x
的值是人的一个实例。可能您错过了这一点?def getKindName[T](隐式x:T)