Scala伴侣对象特性是否可以调用该类的构造函数?

smdncfj3  于 2022-12-13  发布在  Scala
关注(0)|答案(2)|浏览(141)

我正在尝试解决一个在Scala中可能无法解决的问题。
我想有一个特质来解决默认构造函数

trait Builder[T <: Buildable] {
  def build(code: String): T = new T(code)
  def build: T = new T("bar")
}

因此,扩展伴随对象上的Trait会自动访问使用特定构造函数和参数创建类的函数

class A(code: String) extends Buildable

object A extends Builder[A]

扩展Trait,伴随对象具有构造函数

A.build("foo")
A.build

这在Scala中可能吗?
我也尝试过抽象类,但没有任何成功

trait Builder[T <: BuildableClass] {
  def build(code: String): T = new T(code)
  def build: T = new T("bar")
}

abstract class BuildableClass(code: String)

class A(code: String) extends BuildableClass(code)

object A extends Builder[A]

先谢了
编辑:当前在Scala 2.12上锁定

toiithl6

toiithl61#

其中一个潜在的解决方案是使用反射,看起来有点难看,但它是有效的。

import scala.reflect._

trait Builder[T <: Buildable] {
  def build(code: String)(implicit ct: ClassTag[T]): T =
    ct.runtimeClass.getConstructors()(0).newInstance(code).asInstanceOf[T]

  def build(implicit ct: ClassTag[T]): T =
    ct.runtimeClass.getConstructors()(0).newInstance("bar").asInstanceOf[T]
}

trait Buildable

class A(code: String) extends Buildable {
  def getCode = code
}

object A extends Builder[A]

val a: A = A.build
println(a.getCode)

问题是你的Builder特征不知道如何构造你的示例,你可以通过反射从运行时或者通过宏从编译时获得这些信息。

jfgube3f

jfgube3f2#

由于类型擦除,在普通代码中new T只允许用于类类型T,而不是抽象类型/类型参数。
In Scala, is it possible to instantiate an object of generic type T?
How to create an instance of type T at runtime with TypeTags
Class type required but T found
运行时反射的另一种选择(参见@StanislavKovalenko的答案)是宏。new T在那里是可能的,因为在宏扩展期间T还没有被擦除。
第一个
替代实施:
第一个

相关问题