【问题标题】:How to instantiate a structural type in Scala?如何在 Scala 中实例化结构类型?
【发布时间】:2019-09-24 23:30:31
【问题描述】:

我正在尝试在 Scala 中创建结构类型以避免定义中间类。本质上,我只想定义一个结构,该结构将被编组/解组到 JSON 字符串。

比如描述下面的JSON

{
    "query": {
        "range" : {
            "number" : {
                "gte": 123, 
                "lte": 456
            }
        }
    }
}

我有对应的结构类型:

  //structural
  type NumberRange = {val range: {val number: {val gte: Long; val lte: Long}}}

  //named
  case class NumberRangeQuery(query: NumberRange)

  //instance
  val nrq: NumberRangeQuery = ???

创建NumberRangeQuery 实例的正确方法是什么?

【问题讨论】:

  • 如果您在问问题的那一刻就知道答案,为什么要问这个问题?因为你马上就回答了。
  • @RamanMishra 遗憾的是,stackoverflow 鼓励人们提出问题,然后自己回答。见this help topic
  • @RamanMishra 是的,但是根据帮助主题,这是可以的:“如果您有一个问题,您已经知道 [...] 的答案,那么提出并回答您自己的问题是完全可以的在 Stack Exchange 网站上。”
  • @Tim,为什么“悲伤”?在我有机会发布问题之前,我得到了答案。由于答案不是来自 StackOverflow,因此我将我的答案与我的问题一起发布,以便其他人可以从这些信息中受益。我错过了什么吗?
  • @Dmitry 答案是在问题之后发布的,所以有一段时间你的问题在那里但不是你的答案。但真正的问题是,这是一个关于不应该发生的情况的人为问题。

标签: scala duck-typing structural-typing


【解决方案1】:

在这种情况下,答案不是使用结构类型,而是花精力使用案例类并使代码更具可读性和效率:

case class Number(gte: Long, lte: Long)
case class Range(number: Number)
case class Query(range: Range)
case class NumberRangeQuery(query: Query)

val nrq: NumberRangeQuery = NumberRangeQuery(
  Query(
    Range(
      Number(1, 3)
    )
  )
)

在这种情况下,为什么你会选择结构类型而不是具体类型?

【讨论】:

  • 这显然是一个更干净的解决方案,但问题是“如何”实例化结构类型,而不是它是否是正确的做法:)
  • @Dmitry 这是一个经典的XY question,您正在尝试修复您选择的解决方案,而不是解决实际问题。
  • 也许问题不清楚,我应该编辑它。我想使用结构类型的原因是避免用中间(嵌套)值的类“污染”命名空间。
  • 结构类型不是命名空间污染问题的答案。您可以通过简单地将代码放在 {} 中来避免污染命名空间,这样符号就不会逃逸,或者将它们放在 object 中以便它们需要被限定。
  • 您能否在您的答案中添加匿名类初始化的演示?然后它将完成,我会将其标记为已接受。
【解决方案2】:

要创建实现结构类型的类的内联实例,您可以使用以下方法:

//instance
  val nrq: NumberRangeQuery = NumberRangeQuery(new {
    val range = new {
      val number = new {
        val gte = 1: Long 
        val lte = 3: Long
      }
    }
  })

请注意,实例化“匿名”结构类型至少会带来 2 个惩罚:

1) 可以说是可读的代码
2) Scala 将在运行时使用反射来调度此类实例上的方法 (discussion here)

【讨论】:

  • 这不是实例化结构类型。这是创建一个实现结构类型的类并实例化该类。
  • 感谢@JörgWMittag。已更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-22
相关资源
最近更新 更多