首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何对Scala中的case类的所有/某些字段自动应用修改?

如何对Scala中的case类的所有/某些字段自动应用修改?
EN

Stack Overflow用户
提问于 2021-07-29 02:24:31
回答 1查看 113关注 0票数 0

目前,我正在挑战自己在Scala和FP方面的技能。今天:

  • 我想出了一个可能让你感兴趣的问题,魔鬼程序大师;)

假设我在scala 3中有以下案例类:

代码语言:javascript
复制
type EmailAddress = String // I defined them like that to show I'm interested in
type PhoneNumber = String // ... attributes via their names, not via their types.
case class Person(name: String, emails: List[EmailAddress], phones: List[PhoneNumber])

我希望有一个自动转换(几乎)所有字段的方法。例如,我希望使用给定的实例(给定实例的emails of OrderingString )和phones命令(指定的一个)来订购。理想情况下,我应该是,能够排除 name 字段。

所以我会得到这样的东西:

代码语言:javascript
复制
/* Below, I represented the kind of parametrization I would like to be able to do 
 * as parameters of the method orderValues,
 * but it could be annotations or meta-programming instead.
 * 
 * An `orderedPerson` can be directly an instance of Person
 * or something else like an OderedEntity[Person], I don't care so far.
 */
val orderedPerson =
  person.orderValues(
    excluded = Set("name"),
    explicitRules = Map(
      // Phones would have a special ordering (reverse is just a dummy value)
      "phones" -> Ordering.String.reverse
    )
  )

// -----

// So we would get:
Person(
  name = "Xiao",
  emails = List("a@a.a", "a@a.b", "a@b.a"),
  phones = List("+86 100 9000 1000", "+86 100 2000 1000")
)

我已经很久没有使用反射了,我还不熟悉元编程,但是我对任何能够帮助我实现这一目标的解决方案都持开放态度。这是一个学习的好机会!

编辑

我的意图是有一个库,可以用来方便匿名任何数据。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-29 05:57:37

Scala中的type关键字只是一个类型别名。您应该使用newtype库,比如https://github.com/estatico/scala-newtype (或者Scala 3中的opaque type ),并从字符串派生出排序的隐式实例。

使用estatico/scala-newtype的示例

代码语言:javascript
复制
import io.estatico.newtype.macros.newtype
import io.estatico.newtype.ops._

@newtype case class Email(string: String)
object Email {
  implicit val ordering: Ordering[Email] = deriving
}
@newtype case class PhoneNumber(string: String)
object PhoneNumber {
  implicit val ordering: Ordering[PhoneNumber] = deriving[Ordering].reverse
}
case class Person(name: String, emails: List[Email], phones: List[PhoneNumber]) {
  lazy val orderValues: Person = this.copy(emails = emails.sorted, phones = phones.sorted)
}

Person(
  "Xiao",
  List(Email("a@a.a"), Email("a@a.b"), Email("a@b.a")),
  List(PhoneNumber("+86 100 9000 1000"), PhoneNumber("+86 100 2000 1000"))
).orderValues
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68569306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档