假設我正在處理,看上去像一個簡單的冒號分隔的文本協議:慣用的Scala方式
Event:005003:information:2013 12 06 12 37 55:n3.swmml20861:1:Full client swmml20861 registered [entry=280 PID=20864 queue=0x4ca9001b]
RSET:m3node:AUTRS:1-1-24:A:0:LOADSHARE:INHIBITED:0
M3UA_IP_LINK:m3node:AUT001LKSET1:AUT001LK1:r
OPC:m3node:1-10-2(P):A7:NAT0
....
我想反序列化每行的一個實例案例類,但以類型安全的方式。我第一次嘗試使用類型類來爲我可能遇到的每種可能類型定義'read'方法,此外還有case類的'tupled'方法以獲取可以應用於參數元組的函數,類似於以下內容:
case class Foo(a: String, b: Integer)
trait Reader[T] {
def read(s: String): T
}
object Reader {
implicit object StringParser extends Reader[String] { def read(s: String): String = s }
implicit object IntParser extends Reader[Integer] { def read(s: String): Integer = s.toInt }
}
def create[A1, A2, Ret](fs: Seq[String], f: ((A1, A2)) => Ret)(implicit A1Reader: Reader[A1], A2Reader: Reader[A2]): Ret = {
f((A1Reader.read(fs(0)), A2Reader.read(fs(1))))
}
create(Seq("foo", "42"), Foo.tupled) // gives me a Foo("foo", 42)
的問題是,雖然我需要定義每個元組和功能的元數create方法,所以這意味着以創建22個版本。此外,這不涉及驗證或接收損壞的數據。
我真的很喜歡你的解決方案,但如果我正確地理解它,它被鎖定到一個特定的案例班級的大小,不是嗎?你有沒有想辦法讓它更通用? – pommedeterresautee
不確定你的意思*特定的案例類大小*。使用'case class Bar(a:Int,b:Int,c:String)''你可以'Reader [Int :: Int :: String :: HNil] .map(Generic [Bar] .from _)'。但是,它比一個完整的解決方案更像草圖。它根本不會處理變體類型。正如我所說,我對Shapeless不太熟悉,這可能不是最好的。另外,Shapeless 2.0的新版本剛剛推出,可能會讓它變得更容易。 –
我正在嘗試編寫一個csv解析器。解析後,我得到一個字符串列表,但我試圖將其轉換爲提供的案例類,儘可能爲用戶提供儘可能少的樣板代碼。用上面的消息(這是我發現的最好的)顯示的當前解決方案,lib的用戶需要編寫一些代碼來解釋如何將字符串轉換爲它的類類,如您在上一個命令中所述。我會對如何做到這一點的建議感興趣(如果可能的話)。不支持變體類型在我的情況下不會成爲問題。 – pommedeterresautee