【问题标题】:Using structural types as "trait argument"使用结构类型作为“特征参数”
【发布时间】:2017-01-13 10:32:18
【问题描述】:

我正在使用特征作为模块来构建我的代码,我可以根据需要互换插入它们,类似于以下示例:

trait Module1 { def method1 = "method1" }

trait Module2 { def method2 = "method2" }

abstract class BaseClass {
  def doWork: Unit
}

class ClassImpl extends BaseClass with Module1 with Module2 {
  def doWork: Unit = {
    println(method1)
    println(method2)
  }
}

但是,我的一些模块依赖于一些配置变量(用户定义的、运行时参数),如果它们是类,我会将它们作为构造函数参数传递。由于特征不接受参数,我的想法是使用结构类型:

trait Module1 { 
  this: {
    val config1: Int
    val config2: Int
  } =>
  def method1 = s"method1 c1=$config1 c2=$config2"
}

trait Module2 { def method2 = "method2" }

abstract class BaseClass {
  def doWork: Unit
}

case class Config(c1: Int, c2: Int)
class ClassImpl(config: Config) extends BaseClass with Module1 with Module2 {
  protected val config1 = config.c1
  protected val config2 = config.c2
  def doWork: Unit = {
    println(method1)
    println(method2)
  }
}

这是配置我的模块的好策略还是有更好的策略?

【问题讨论】:

    标签: scala


    【解决方案1】:

    结构类型涉及反射,是否确实有更好的解决方案,请考虑以下示例:

    trait Module[F,S] { this: Config[F,S] =>
      def method = s"method1 c1=$config1 c2=$config2"
    }
    
    trait Config[F,S] {
      def config1: F
      def config2: S
    }
    
    case class DefaultConfig[T,S](config1: T, config2: S) extends Config[T,S]
    
    case class ConfigCls(c1: Int, c2: Int)
    class ClassImpl(config: ConfigCls) extends DefaultConfig(config.c1, config.c2) with Module[Int,Int] {
      def doWork(): Unit = {
        println(method)
      }
    }
    

    这样你就可以避免使用结构类型,做的事情基本上和你原来的帖子一样。

    【讨论】:

    • 感谢您的意见。这似乎是一个不错的方法,但是如果我有不同的特征模块,每个特征模块都有一组不同的配置变量,它是如何工作的?我是否需要在 Config 特征中包含所有这些变量的并集?
    • 你可以为每个模块(ModuleA -> ConfigA 等)定义配置特征而不是创建:class DefaultConfig(...) extends ConfigA with ConfigB ... with ConfigZ
    • 我明白了,谢谢。另一个问题:在我的项目中,“ClassImpl”类已经扩展了另一个类,那么如何让它扩展 DefaultConfig?我必须让父类扩展 DefaultConfig 吗?
    • 如果你想使用 scala 方法覆盖语法糖,这是对这种模式的限制,我现在无法想象干净的解决方案。您始终可以手动覆盖方法,而不必扩展 DefaultConfig
    猜你喜欢
    • 1970-01-01
    • 2019-06-11
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多