我正在尝试在Scala中编写一个不带参数的方法,并且将使用泛型类型在方法中执行某些逻辑,该逻辑将仅基于泛型类型返回输出(类似于asInstanceOf[T]
或isInstanceOf[T]
)。
它应该是这样的:
val myObj = new MyClass
myObj.instanceOf[MyClass]
// returns true
这是我认为可行的。
class MyClass {
def instanceOf[Class[_]]: Bool = {
// ???
}
}
我该如何实现?
谢谢。
答案 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]]
这在两种情况下很有用:
使用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
您的方法采用隐式证据,但您不使用implicit
arg列表,而是使用类型绑定,稍后您希望使用{{抓取类型类的实例1}}:
implicitly
而不是:
def myMethod[T: FooTC[T, Int]](t: T) = {
val ev = implicitly[FooTC[T, Int]]
ev.doSmth(t)
}
P.S。在stdlib中,def myMehtod[T](t: T)(implicit ev: FooTC[T, Int]) = {
ev.doSmth(t)
}
实现如下:
implicitly