我需要一种通用方法(例如某些函数),它接受case类(任何类型)的实例,并返回此实例的副本,但带有修剪后的字符串。
(最好没有反思)
有什么想法吗?
答案 0 :(得分:3)
您可以使用shapeless执行此操作:
import shapeless._
import shapeless.ops.hlist._
// Trims if passed a String value, otherwise returns the value unchanged
object Trimmer extends Poly1 {
implicit val stringTrim = at[String] { _.trim }
implicit def noop[T] = at[T] { identity }
}
// Uses a Generic to transform the instance into an HList, maps over it
// and convert it back into the case class
def trimCaseClass[C, H <: HList](c: C)
(implicit g: Generic.Aux[C, H], m: Mapper.Aux[Trimmer.type, H, H]): C = {
val hlist = g.to(c)
val trimmed = hlist.map(Trimmer)
g.from(trimmed)
}
然后:
scala> case class A(s1: String, s2: String, i: Int)
defined class A
scala> val a = A(" 1 ", "2", 3)
a: A = A( 1 ,2,3)
scala> trimCaseClass(a)
res0: A = A(1,2,3)
答案 1 :(得分:2)
使用shapeless:
import shapeless._, ops.hlist._
object trimString extends Poly1 {
implicit val stringCase = at[String](_.trim)
implicit def restCase[A] = at[A](a => a)
}
def trimAllIn[A, R <: HList](a: A)(implicit
gen: Generic.Aux[A, R],
mapper: Mapper.Aux[trimString.type, R, R]
) = gen.from(mapper(gen.to(a)))
case class Foo(string: String, int: Int)
case class Bar(string1: String, string2: String)
assert { trimAllIn(Foo(" trim me ", 42)) == Foo("trim me", 42) }
assert { trimAllIn(Bar(" trim me", "and me too ")) == Bar("trim me", "and me too") }
Runnable version here