问题描述
假设我有一个专门的类和一个关联的伴侣对象:
trait Slice [@specialized + T] {
...
覆盖def等于(that:any)=匹配{
case s:Slice [_] => ???
case _ =>假
}
}
对象切片{
def newInstance [@specialized T] = ???
$ / code>
有没有办法检查
- 如果此实例是专用子类,则在Slice的一个方法内部
- 如果另一个实例是相同的原语,
- 如果我正在运行擦除或专用变体,则在伴随对象的专用方法内
而不诉诸ClassTags或手动传递Class [_]?这似乎应该是可用的信息,但我能想到的唯一方法涉及检查类的名称。
使用情况2)是特别重要的,因为我可以如果我是新手,我会将苹果与苹果进行比较,并诉诸更快的算法。它可能通过反射来完成,但是如果考虑到我们还必须处理Slice的非合成子类,那么它会非常棘手;如果我们还有
$ $ $ $ p $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $特性$ / code>
只要它们都是专用的(或两者都被擦除),应该认为它们与Slice [T]实例'兼容'?
好吧,我想出了一个更清晰的方式:
<$ p $ (特殊字符,短,中,长,字符,浮点,双精度,布尔,任何引用)
def specializationFor [@specialized (AllButUnit)E]:ResolvedSpecialization [E] =
Specializations(new SpecializedKey [E])。asInstanceOf [ResolvedSpecialization [E]]
private val Specializations = Seq(
解析[Byte],
解析[Short],
解析[Int],
解析[Long],
解析[Char],
解析[
resolve [Boolean],
resolve [Double],
resolve [Boolean] spec => spec.key - & (特殊键[_],ResolvedSpecialization [_])
).toMap.withDefaultValue(resolve [AnyRef])
private def resolve [@specialized(AllButUnit)E:ClassTag ]:ResolvedSpecialization [E] =
ResolvedSpecialization [E](new SpecializedKey [E],new Array [E](0))
class ResolvedSpecialization [@specialized AllButUnit)E] private [SpecializedCompanion]
(val array:Array [E],val elementType:Class [E],val classTag:ClassTag [E],private [SpecializedCompanion] val key:SpecializedKey [E])
{
private [SpecializedCompanion] def this(key:SpecializedKey [E],array:Array [E])=
this(array,array.getClass.getComponentType.asInstanceOf [Class [E] ],ClassTag(array.getClass.getComponentType.asInstanceOf [Class [E]]),key)
override def toString = s@specialized($ elementType)
覆盖def等于(那:任何)=匹配{
案例r:ResolvedSpecialization [_] => r.elementType == elementType
case _ => false
override def hashCode = elementType.hashCode
}
private class SpecializedKey [@specialized(AllButUnit)E] {
重写def equals(that:Any)= that.getClass == getClass
override def hashCode = getClass.hashCode
def className = getClass.getName
override def toString = className。 substring(className.indexOf($)+ 1)
}
现在 specializationFor [E] .elementType
返回对应于E的特化参数的类。
Let's say I have a specialized class and an associated companion object:
trait Slice[@specialized +T] {
...
override def equals(that :Any) = that match {
case s :Slice[_] => ???
case _ => false
}
}
object Slice {
def newInstance[@specialized T] = ???
}
Is there any way to check
- Inside a method of Slice if this instance is a specialized subclass,
- Inside a method of Slice if another instance is a specialized subclass for the same primitive,
- Inside a specialized method on a companion object if I'm running an erased or specialized variant
without resorting to ClassTags or passing Class[_] manually? It seems like that information should be available, but the only way I can think of involves checking names of the classes.
Use case 2) is particularly important, as I could resort to faster algorithms if I new I'm comparing apples with apples. It probably could be accomplished by reflection, but it would be quite tricky when you take into account that we have to handle non-synthetic subclasses of Slice, too; if we have also
trait ArraySlice[@specialized T] extends Slice[T] { ... }
that should be considered 'compatible' with Slice[T] instances as long as they are both specialized (or both erased)?
Ok, I figured out a cleaner way:
final val AllButUnit = new Specializable.Group((Byte, Short, Int, Long, Char, Float, Double, Boolean, AnyRef))
def specializationFor[@specialized(AllButUnit) E] :ResolvedSpecialization[E] =
Specializations(new SpecializedKey[E]).asInstanceOf[ResolvedSpecialization[E]]
private val Specializations = Seq(
resolve[Byte],
resolve[Short],
resolve[Int],
resolve[Long],
resolve[Char],
resolve[Float],
resolve[Double],
resolve[Boolean],
resolve[Unit],
resolve[AnyRef]
).map(
spec => spec.key -> spec :(SpecializedKey[_], ResolvedSpecialization[_])
).toMap.withDefaultValue(resolve[AnyRef])
private def resolve[@specialized(AllButUnit) E :ClassTag] :ResolvedSpecialization[E] =
new ResolvedSpecialization[E](new SpecializedKey[E], new Array[E](0))
class ResolvedSpecialization[@specialized(AllButUnit) E] private[SpecializedCompanion]
(val array :Array[E], val elementType :Class[E], val classTag :ClassTag[E], private[SpecializedCompanion] val key :SpecializedKey[E])
{
private[SpecializedCompanion] def this(key :SpecializedKey[E], array :Array[E]) =
this(array, array.getClass.getComponentType.asInstanceOf[Class[E]], ClassTag(array.getClass.getComponentType.asInstanceOf[Class[E]]), key)
override def toString = s"@specialized($elementType)"
override def equals(that :Any) = that match {
case r :ResolvedSpecialization[_] => r.elementType==elementType
case _ => false
}
override def hashCode = elementType.hashCode
}
private class SpecializedKey[@specialized(AllButUnit) E] {
override def equals(that :Any) = that.getClass==getClass
override def hashCode = getClass.hashCode
def className = getClass.getName
override def toString = className.substring(className.indexOf("$")+1)
}
Now specializationFor[E].elementType
returns class corresponding to specialization parameter of E.
这篇关于如何检查我在scala中运行时在@specialized函数或类中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!