说我有一个类似的案例类:
PrintWriter
这也存储在一个文件中,每行看起来像:
StringWriter
我想在一个用户对象和一个地方的字符串表示之间来回执行此解析。
在Scala中执行此操作的最佳方法是什么?
我知道我可以做一个字符串拆分,但想知道他们是否更清洁,更惯用。
答案 0 :(得分:3)
/**
* Serialization/deserialization API
*/
trait Codec[T] {
def parse(str: String):Option[T]
def write(u: T): String
implicit def string2type(str: String):Option[T] = parse(str)
implicit def type2string(u: T):String = write(u)
implicit def iterable2type(it: Iterable[String]):Iterable[T] =
it.flatMap(string2type)
}
/**
* Serialization/deserialization implementation for User
*/
object UserCodec extends Codec[User] {
val pattern = """(\d+)\|"([\w\s]+)"\|(\d+)""".r
override def parse(str: String):Option[User] = str match {
case pattern(id, name, age) => Some(User(id.toInt, name, age.toInt))
case _ => None
}
override def write(u: User): String = s"""${u.id}|"${u.name}"|${u.age}"""
}
用法:
def main(args: Array[String]): Unit = {
import UserCodec._
val str = """123|"john asd"|35"""
val u:Option[User] = str
val s:String = User(1, "a", 1)
println(u) // out: Some(User(123,john asd,35))
println(s) // out: 1|"a"|1
}
<强> UPD:强> 迭代的示例:
def main(args: Array[String]): Unit = {
import UserCodec._
val lines = Seq(
"""1|"john"|34""",
"""2|"bill"|35""",
"""3|"aaa"|36"""
)
val validUsers: Iterable[User] = lines
println(validUsers.toList)
//out:List(User(1,john,34), User(2,bill,35), User(3,aaa,36))
}