简体   繁体   English

Scala类的构造函数隐式参数是字段吗?

[英]scala class constructor implicit paramaters are fields?

Do implicit parameters in a class constructor behave like regular parameters in a way that if they are referenced somewhere inside that class they automatically become fields ? 类构造函数中的隐式参数是否像常规参数那样以某种方式工作,如果它们在该类内部某个地方被引用,它们会自动成为字段?

If so how to avoid that in this case: 如果是这样,在这种情况下如何避免这种情况:

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

If I need to create a lot of those triangles, each instance will contain reference to Addable resulting in increased memory use. 如果需要创建大量三角形,则每个实例都将包含对Addable的引用,从而导致内存使用量增加。

Interesting question. 有趣的问题。 I didn't know and I decided to check. 我不知道,所以我决定检查一下。 I see a field is created for each implicit parameter: 我看到为每个隐式参数创建了一个字段:

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)
  } 
}

The output: 输出:

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>: <?>]

Yes, of course, there would be no other way to do it (as @puhlen pointed out). 是的,当然,没有其他方法可以做到(如@puhlen所指出的)。 As an alternative, you could move ev to methods which use it: 或者,您可以将ev移至使用它的方法:

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

but note that this changes semantics: it requires that the Addable be in scope at method call site, not when you create the triangle. 但是请注意,这会改变语义:它要求Addable在方法调用站点的作用域内,而不是在创建三角形时。

As a side note, I wouldn't expect @specialized to be helpful at all when T by itself isn't used anywhere. 附带说明一下,当T本身未在任何地方使用时,我不希望@specialized完全有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM