scala – 以类型安全的方式将Seq [String]转换为case类
我编写了一个解析器,它根据一些规则将String转换为Seq [String].这将在库中使用.
我试图将此Seq [String]转换为case类.案例类将由用户提供(因此无法猜测它将是什么). 我曾经想过无形的库,因为它似乎实现了很好的功能,看起来很成熟,但我不知道如何继续. 我发现了这个问题with an interesting answer,但我找不到如何根据我的需要改造它.实际上,在答案中只有一种类型要解析(String),并且库在String本身内部迭代.它可能需要对事情的完成方式进行深刻的改变,我不知道如何做. 此外,如果可能的话,我想让我的图书馆用户尽可能简化这个过程.因此,如果可能,与上面链接中的答案不同,HList类型将从案例类本身猜测(但是根据我的搜索,似乎编译器需要此信息). 我对类型系统和所有这些美好的东西有点新,如果有人能给我一个如何做的建议,我会很开心! 亲切的问候 —编辑— 正如ziggystar所要求的,这里有一些可能需要的签名: //Let's say we are just parsing a CSV. @onUserSide case class UserClass(i:Int,j:Int,s:String) val list = Seq("1,2,toto","3,4,titi") // User transforms his case class to a function with something like: val f = UserClass.curried // The function created in 1/ is injected in the parser val parser = new Parser(f) // The Strings to convert to case classes are provided as an argument to the parse() method. val finalResult:Seq[UserClass] = parser.parse(list) // The transfomation is done in two steps inside the parse() method: // 1/ first we have: val list = Seq("1,titi") // 2/ then we have a call to internalParserImplementedSomewhereElse(list) // val parseResult is now equal to Seq(Seq("1","2","toto"),Seq("3","4","titi")) // 3/ finally Shapeless do its magick trick and we have Seq(UserClass(1,UserClass(3,"titi)) @insideTheLibrary class Parser[A](function:A) { //The internal parser takes each String provided through argument of the method and transforms each String to a Seq[String]. So the Seq[String] provided is changed to Seq[Seq[String]]. private def internalParserImplementedSomewhereElse(l:Seq[String]): Seq[Seq[String]] = { ... } /* * Class A and B are both related to the case class provided by the user: * - A is the type of the case class as a function,* - B is the type of the original case class (can be guessed from type A). */ private def convert2CaseClass[B](list:Seq[String]): B { //do something with Shapeless //I don't know what to put inside ??? } def parse(l:Seq[String]){ val parseResult:Seq[Seq[String]] = internalParserImplementedSomewhereElse(l:Seq[String]) val finalResult = result.map(convert2CaseClass) finalResult // it is a Seq[CaseClassProvidedByUser] } } 在库内部,一些隐式的可用于将String转换为正确的类型,因为它们是由Shapeless猜测的(类似于上面链接中提出的答案).像string.toInt,string.ToDouble等… 可能还有其他方式来设计它.这是我玩Shapeless几个小时后的想法. 解决方法
这使用了一个名为
product-collecions的非常简单的库
import com.github.marklister.collections.io._ case class UserClass(i:Int,s:String) val csv = Seq("1,titi").mkString("n") csv: String = 1,toto 3,titi CsvParser(UserClass).parse(new java.io.StringReader(csv)) res28: Seq[UserClass] = List(UserClass(1,toto),titi)) 并以其他方式序列化: scala> res28.csvIterator.toList res30: List[String] = List(1,"toto",3,"titi") product-collections面向csv和java.io.Reader,因此上面的垫片. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |