在Scala中如何将一个案例类转换为另一个不受代码更改字段添加影响的类? [英] in scala how to convert one case class to another immune to code changes field additions?

查看:35
本文介绍了在Scala中如何将一个案例类转换为另一个不受代码更改字段添加影响的类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

case class Cat(color: Int, isFat: Boolean)
case class Kitten(color: Int, isFat: Boolean)

我想从 Cat 构造 Kitten 但想在不传递所有参数的情况下自动完成(因此,如果我向 Cat/Kitten 添加更多字段,则不需要更改代码).有没有一种紧凑的方法可以在 Scala 中实现这一点?

I want to construct Kitten from Cat but want to do it automatically without passing all parameters (so if i add more field to Cat / Kitten I would not need to change code). Is there a compact way to achieve that in scala?

val kitten = Cat(1,True).what_to_do_here? // compact & immune to code changes no need to change that line in case of added fields.

推荐答案

你可能想看看 Shapeless.

import shapeless._
import shapeless.syntax._


case class Cat(color: Int, isFat: Boolean)
case class Kitten(color: Int, isFat: Boolean)

val kitten = Kitten(2, true)

val genCat = Generic[Cat]
val genKit = Generic[Kitten]

val cat: Cat = genCat.from(genKit.to(kitten))

println(cat)

Shapeless 是一个用于通用编程的库.例如,泛型类型类可以将密封特征和案例类(例如 CatKitten)的任何层次结构的实例转换为泛型表示(HLists 和 Coproducts),并且回到任何兼容的类层次结构.可以以类型安全的方式操作介于两者之间的通用表示.

Shapeless is a library for generic programming. For example, the Generic typeclass can convert instances of any hierarchy of sealed traits and case classes (such as Cat and Kitten) into a generic representation (HLists and Coproducts), and back into any compatible class hierarchy. The generic representation in between can be manipulated in a type safe manner.

genKit.to(kitten) 接受一个 Kitten,并产生一个 HList 2 :: true :: HNil.由于这与 Cat 的通用表示兼容而无需修改,因此可以使用 genCat.from 存储它.

genKit.to(kitten) takes a Kitten, and produces a HList 2 :: true :: HNil. Since that is compatible with the generic representation of Cat without modification, it can be stored as such using genCat.from.

在这种情况下,CatKitten 几乎相同.如果类型的顺序不同,或者 Kitten 有一个额外的属性怎么办?如果每个属性的名称都很重要怎么办?Shapeless 中有大量有用的东西,可以通过操纵通用表示轻松解决这类情况.看看这个 示例,其中使用 LabelledGeneric(使用带有标签的 HLists,又名 Records)转换某些类型的 Book,添加一个属性并存储到 ExtendedBook.所有这些都是类型安全的.

In this case, Cat and Kitten are nearly identical. What if the order of types was different, or Kitten had an extra property? What if the name of each property is significant? There is tons of useful stuff in Shapeless to easily solve exactly these kind of situations by manipulating the generic representation. Take a look at this example, where some type Book is converted using LabelledGeneric (which uses a HLists with labels, a.k.a. Records), a property is added, and stored into ExtendedBook. All of this type-safe.

Shapeless 确实使用了一些宏,但似乎只依赖于它们的最小集合.Shapeless 的用户不会自己编写任何宏 - 繁重的工作由 Scala 强大的类型系统完成.

Shapeless does use some macros, but seemingly relies only on a minimal set of them. The user of Shapeless does not write any macros him/herself - the heavy lifting is done by Scala's powerful type system.

这篇关于在Scala中如何将一个案例类转换为另一个不受代码更改字段添加影响的类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆