加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 以类型安全的方式将Seq [String]转换为case类

发布时间:2020-12-16 18:46:56 所属栏目:安全 来源:网络整理
导读:我编写了一个解析器,它根据一些规则将String转换为Seq [String].这将在库中使用. 我试图将此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,因此上面的垫片.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读