scala泛型编程中的c ++静态成员

时间:2017-07-20 07:44:56

标签: scala generics

我曾经是一个c ++程序员,是scala的新手。 我在scala中做了一些通用编程,比如

   class FooComponent
    {
     public:
       static const int ComponentId = 1;
    }
    class BarComponent
    {
     public:
       static const int ComponentId = 2;
    }
    template<typename T>
    void registerComponent()
    {  
       register(T::ComponentId)
    }

但是在scala中没有类静态变量。我知道有伴随对象,但我不能只通过类型参数访问伴随对象。

在scala中获得类似函数的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

你可以使用结构类型接近这一点。但据我所知,你不能将它与伴侣对象的静态成员结合起来。

class FooComponent{
  val ComponentId = 1
}

class BarComponent{
  val ComponentId = 2
}

object Main extends App{
  def register(t: {val ComponentId:Int} ) = println(t.ComponentId)

  register(new BarComponent())  // -> 2
  register(new FooComponent())  // -> 1
}

如果您需要同时访问实例和类对象,则可以执行以下操作:

class FooComponent{
  val ComponentId = FooComponent.ComponentId
}
object FooComponent{
  val ComponentId = 1
}

class BarComponent{
  val ComponentId = BarComponent.ComponentId
}
object BarComponent{
  val ComponentId = 2
}

object Main extends App{
  def register(t: {val ComponentId:Int} ) = println(t.ComponentId)

  register(BarComponent)      // -> 2
  register(new BarComponent)  // -> 2
  register(FooComponent)      // -> 1
  register(new FooComponent)  // -> 1

  println(FooComponent.ComponentId)   // -> 1
}

答案 1 :(得分:0)

如果你真的只想使用类型参数(并且更像模板),你可以用宏来做:

在宏项目中创建实际的宏

#include

}

在项目中使用宏

import scala.reflect.macros.blackbox

object MyMacroImpl {
 def registerMacro[T: c.WeakTypeTag](c: blackbox.Context): c.universe.Tree = {
  import c.universe._

  val tpe = weakTypeOf[T]
  val companion = tpe.typeSymbol.companion

  q"""MyMacro.register(${companion.name.toTermName}.componentId)"""

编辑:就个人而言,我会像这样实现它:

class FooComponent
object FooComponent {
  val componentId: Int = 1
}

class BarComponent
object BarComponent {
  val componentId: Int = 2
}

object MyMacro {
  def registerComponent[T]: Unit = macro MyMacroImpl.registerMacro[T]
}

object Main {
  def register(id: Int): Unit = println(id)

  MyMacro.registerComponent[FooComponent]
}

没有宏(因此复杂性更低),没有对象的实例化,结果几乎相同。