类构造函数中的隐式参数是否像常规参数一样,如果它们被引用到该类中的某个位置,它们会自动成为字段?
如果是这样,在这种情况下如何避免:
class Triangle[@specialized T, V[_]](p1:V[T],p2:V[T],p3:V[T])(implicit ev: Addable[V[T]]){
def someFuncThatUsesAddable(): Any = ???
}
如果我需要创建很多这些三角形,每个实例都会包含对Addable的引用,从而导致内存使用量增加。
答案 0 :(得分:0)
有趣的问题。我不知道,我决定检查。我看到为每个隐式参数创建了一个字段:
import scala.reflect.runtime.{universe => ru}
class X
class A()
class B(val i: Int)
class C(val i: Int)(implicit x: X)
object Xc extends App {
implicit val x = new X()
def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
def allDecls(d: ru.MemberScope) = d.mkString("[", ",", "]")
def printTypeInfo(typeA: ru.Type) =
println(s"type ${typeA.typeSymbol} has ${typeA.members.size}
members. Declarations: " + allDecls(typeA.decls))
printTypeInfo(getTypeTag(new A()).tpe)
printTypeInfo(getTypeTag(new B(1)).tpe)
printTypeInfo(getTypeTag(new C(1)).tpe)
}
}
输出:
type class A has 22 members. Declarations: [def <init>: <?>]
type class B has 24 members. Declarations: [val i: <?>,private[this] val i: <?>,def <init>: <?>]
type class C has 25 members. Declarations: [val i: <?>,private[this] val i: <?>,implicit private[this] val x: <?>,def <init>: <?>]
答案 1 :(得分:0)
是的,当然,没有别的方法可以做到(正如@puhlen指出的那样)。作为替代方案,您可以将ev
移动到使用它的方法:
class Triangle[@specialized T, V[_]](p1:V[T],p2:V[T],p3:V[T]) {
def someFuncThatUsesAddable(implicit ev: Addable[V[T]]): Any = ???
}
但请注意,这会改变语义:它要求Addable
在方法调用站点的范围内,而不是在创建三角形时。
作为旁注,当@specialized
本身并未在任何地方使用时,我都不希望T
有所帮助。