Performance scala类构造函数隐式参数是字段吗?

Performance scala类构造函数隐式参数是字段吗?,performance,scala,implicit,Performance,Scala,Implicit,类构造函数中的隐式参数的行为是否与常规参数类似,如果它们在该类中的某个位置被引用,它们会自动成为字段 如果是,在这种情况下如何避免: class Triangle[@specialized T, V[_]](p1:V[T],p2:V[T],p3:V[T])(implicit ev: Addable[V[T]]){ def someFuncThatUsesAddable(): Any = ??? } 如果我需要创建很多这样的三角形,每个实例都将包含对Addable的引用,从而增加内存使用。

类构造函数中的隐式参数的行为是否与常规参数类似,如果它们在该类中的某个位置被引用,它们会自动成为字段

如果是,在这种情况下如何避免:

class Triangle[@specialized T, V[_]](p1:V[T],p2:V[T],p3:V[T])(implicit ev: Addable[V[T]]){
   def someFuncThatUsesAddable(): Any = ???
}

如果我需要创建很多这样的三角形,每个实例都将包含对Addable的引用,从而增加内存使用。

有趣的问题。我不知道,我决定去检查一下。我看到为每个隐式参数创建了一个字段:

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>: <?>]
A类有22个成员。声明:[定义:]
B类有24个成员。声明:[val i:,private[this]val i:,def:]
C类有25个成员。声明:[val i:,private[this]val i:,隐式private[this]val x:,def:]

是的,当然,没有其他方法可以做到这一点(正如@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
本身没有在任何地方使用,我就不指望
@specialized
会有任何帮助。

如果对单个对象的引用太多真的成为问题,你就有更大的问题要担心。@wheaties,这不是问题的全部。三角形的每个实例都会获得一个额外的字段
ev
。这正是我想要避免的。@Rulli当然会创建一个字段,如果不将对象存储在字段中,那么以后在需要时如何使用该对象?是的,我想三角形本身必须使用类型类模式来删除这些字段。让trait实现所有三角形行为,然后为一个只包含三个点的特定简单类提供实现。