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 _:

Scala遭受了类型擦除,但它还引入了类型标签,以克服类型擦除问题

有时,我们可以使用隐式参数(甚至值参数也足够)来解决我们遇到的相同问题

例如:

// 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 _ => ???
    }
}
因此,我的问题是:

  • 为什么以及何时使用类型标记和隐式参数
  • 类型标记和隐式参数之间的性能差异是什么
如果你能给我一个scala中的doc链接来证明你的观点,那就太完美了。先谢谢你

  • TypeTag
    s几乎总是用作隐式参数。如果您不知道,
    getKindName[t:TypeTag]
    表示
    getKindName[t](隐式标记:TypeTag[t])
    。 例外情况是,当您将作为隐式参数获得的
    TypeTag
    存储在某处时。因此,“隐式参数vs
    TypeTag
    ”一开始就没有意义

  • 这两个代码片段的行为根本不相似,因此它们不可能解决同一个问题,不管这个问题是什么。例如,你可以定义

    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)