Scala中的一个方法,它不带参数并使用泛型类型

时间:2014-06-16 21:53:49

标签: scala generics

我正在尝试在Scala中编写一个不带参数的方法,并且将使用泛型类型在方法中执行某些逻辑,该逻辑将仅基于泛型类型返回输出(类似于asInstanceOf[T]isInstanceOf[T])。

它应该是这样的:

val myObj = new MyClass
myObj.instanceOf[MyClass]
// returns true

这是我认为可行的。

class MyClass {
  def instanceOf[Class[_]]: Bool = {
    // ???
  }
}

我该如何实现?

谢谢。

3 个答案:

答案 0 :(得分:2)

您可以使用ClassTags获取传入的类型并使用它。

标题中提到的一个人为的例子是:

class Foo(name: String) {
  def nameMatches[T: ClassTag]() =
    classTag[T].runtimeClass.getName == name
}

new Foo("java.lang.String").nameMatches[String] //> res1: Boolean = true
new Foo("boolean").nameMatches[Boolean]         //> res2: Boolean = true

答案 1 :(得分:1)

这适用于您提供的示例。

import scala.reflect.runtime.universe._

class MyClass { 
  def instanceOf[T: TypeTag] = typeOf[this.type] <:< typeOf[T] 
}

请注意,当您展开MyClass时,您需要覆盖instanceOf才能获得正确的行为。否则你会得到这个:

scala> class MySubClass extends MyClass
defined class MySubClass

scala> (new MySubClass).instanceOf[MyClass]  // works
res3: Boolean = true

scala> (new MySubClass).instanceOf[Any]  // works
res4: Boolean = true

scala> (new MySubClass).instanceOf[MySubClass]  // doesn't work
res5: Boolean = false

答案 2 :(得分:0)

通用方法的另一个例子是标准库的implicitly,您可以自己轻松实现:

def implicitly[T](implicit ev: T) = ev

所以你可以做一些事情,比如查找类型类实例:

trait Show[T] { def shows(t: T): String }
case class Person(name: String, age: Int)
implicit val personShow = new Show[Person] { def show(p: Person) = s"${p.name} @ ${p.age} years" }

implicitly[Show[Person]]

这在两种情况下很有用:

  1. 使用def定义一个非平凡类型的类实例(即你通常从其他类型类的实例“生成”类型类实例)并且你不确定你是否正确:< / p>

    implicit def terriblyNonTrivialTCInstance[T, U, V, W, Ñ](implicit ev1: Foo, ev2: Bar, ev3: Baz, ...): FooTC[T, U] = ...
    
    implicitly[FooTC[MyType1, MyType2]]  // compile error if the above definition is badly constructed
    
  2. 您的方法采用隐式证据,但您不使用implicit arg列表,而是使用类型绑定,稍后您希望使用{{抓取类型类的实例1}}:

    implicitly

    而不是:

    def myMethod[T: FooTC[T, Int]](t: T) = {
      val ev = implicitly[FooTC[T, Int]]
      ev.doSmth(t)
    }
    
  3. P.S。在stdlib中,def myMehtod[T](t: T)(implicit ev: FooTC[T, Int]) = { ev.doSmth(t) } 实现如下:

    implicitly