Scala - konverze TupleN na case class

V projektu chanminer používám pro dotazování relační databáze
ScalaQuery, která vrací instance TupleN neboli
uspořádané n-tice (a tak je to správně). Někdy je potřeba převést tuto n-tici
na objekt určité třídy, která má všechny potřebné metody a „popisná jména členských proměnných .(místo nicneříkajících _1
, _2
atd.)“.
Představte si, že mám třídu Post
:
case class Post( uid: Int, board: String, threadId: Int, id: Int, postername: String, tripcode: String, text: String)
Databázový dotaz mi vrátí Tuple7[Int, String, Int, Int, String, String, String]
jako například:
val t = (9, "b", 323822047, 323856408, "Anonymous", "", "reported")
Převedení n-tice na instanci třídy není nijak zvlášť zapeklité:
def makePost(t: (Int, String, Int, Int, String, String, String)) = Post(t._1, t._2, t._3, t._4, t._5, t._6, t._7)
Nebo s pomocí zázraků pattern matchingu:
def makePost2(t: (Int, String, Int, Int, String, String, String)) = { val (uid, board, threadId, id, postername, tripcode, text) = t Post(uid, board, threadId, id, postername, tripcode, text) }
Tohle řešení funguje, ale je zdlouhavé a s každým dalším prvkem v n-tici/třídě přibude dalších pár znaků.
Naštěstí máme při ruce zázrak konverze metody na funkční objekt a jeho metodu
tupled
+ fakt, že každá case class
má svůj companion objekt s metodou
apply
, která slouží jako zkrácený kontruktor (však víte: Post(...)
se
expanduje na Post.apply(...)
a apply volá new Post(...)
).
Takže když tohle všechno víme, můžeme konverzi provést mnohem stručněji:
val makePostApply = (Post.apply _).tupled val post: Post = makePostApply(t)
Pro obyčejné třídy musíme napsat o několik podtržítek více:
val makePostNew = (new Post(_, _, _, _, _, _, _)).tupled val post: Post = makePostNew(t)
Případně si tuto metodu definovat přímo na companion objektu:
object Post { val fromTuple = (Post.apply _).tupled }