从数据容器(例如案例类)中提取类型的最佳方法是什么。
例如,如果我有一个type Tagged[U] = { type Tag = U}
标记类型trait PID
,它是标记的 Inttype ProductId = Int with Tagged[PID]
或 scalaz 样式type ProductId = Int @@ PID
,并说产品中的其他字段type Name = String @@ PName
等,以及一个包含产品属性的数据容器;
case class Product(pid: ProductId, name: Name, weight: Weight)
我怎样才能编写一个通用的提取器A => B
样式方法而不求助于反射?
原因是我想在运行时从 Product 容器中动态提取一个字段。即用户传入他们想要提取的产品的属性。
即,如果我想动态获取ProductId
,我可以编写一个采用类型并返回值的方法,例如
trait Extractor[A] {
def extract[B](i: A): B = //get type B from the Product class
}
还是我把事情复杂化了。
我可以编写简单的提取器类,它采用 A => B 函数并为每种类型定义它;
trait Getter[A, B] {
def extract(i: A): B
}
//... mix this in...
trait GetPID extends Getter[Product, ProductId] {
override def extract(implicit i: Product) = i.pid
}
trait GetName extends Getter[Product, Name] {
override def extract(implicit i: Product) = i.name
}
然后在需要的地方添加它们。
val dyn = new DynamicProductExtractor with GetPID
dyn.extract
但这似乎很麻烦。
我觉得 Lens 之类的东西在这里会很有用。