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

我想从 Cat 构造 Kitten 但想在不传递所有参数的情况下自动完成(因此,如果我向 Cat/Kitten 添加更多字段,则不需要更改代码)。有没有一种紧凑的方法可以在 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 是一个用于泛型编程的库。例如,泛型类型类可以将密封特征和案例类(例如 Cat 和 Kitten)的任何层次结构的实例转换为泛型表示(HLLists 和 Coproducts),并返回到任何兼容的类层次结构。之间的通用表示可以以类型安全的方式进行操作。
genKit.to(kitten)需要一个 Kitten ,并产生一个 HList 2 :: true :: HNil .因为这与 Cat 的通用表示兼容无需修改,可以使用 genCat.from 将其存储为原样.

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

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


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!