J'ai généré un code scala en utilisant slick codegen. Je vois que certaines tables Rows sont implémentées en tant que HLists. (mais ce sont des HList lisses, pas les HList sans forme normale)Récupérer des éléments de Slick HLIST (ou Convertir Slick HLIst en HList Shapeless)
Maintenant je veux qu'un élément spécifique de la liste HList soit retourné comme une ligne par la requête slick.
Je googlé et trouvé ce fil
Getting elements from an HList
Mais cela ne fonctionne pas pour HList lisse. il fonctionne très bien pour Shapeless HList
J'ai aussi essayé la méthode apply
val x: Long = slickHList (2)
mais cela ne compile pas, car le type Tout ne se conforme pas le type de exected Longue. Je détesterais faire un .asInstanceOf
Existe-t-il une manière de typesafe dans laquelle je peux accéder aux éléments du HList lisse?
Edit: Basé sur l'entrée ci-dessous j'ai écrit le code ci-dessous
package com.abhi
object SlickAndShapeless {
import slick.collection.heterogeneous.{HCons, HList, HNil}
import slick.collection.heterogeneous.syntax.HNil
type MyRow = HCons[Long, HCons[String, HNil]]
val row : MyRow = 1L :: "foo" :: HNil
import HListExtensions._
val hlist = row.asShapeless
val container = new Container(hlist)
val item = container.get(1)
}
class Container[L <: shapeless.HList](list: L) {
import shapeless._
import nat._
import ops.hlist._
def get(n: Nat)(implicit at: At[L, n.N]): at.Out = list[n.N]
}
object HListExtensions {
import slick.collection.heterogeneous.{HNil => SHNil, HList => SHList, HCons}
import shapeless.{::, HList, HNil}
implicit class HListShapelessSlick(val list: HList) extends AnyVal {
def asSlick : SHList = list match {
case HNil => SHNil
case head :: tail => head :: tail.asSlick
}
}
implicit class HListSlickShapeless(val list: SHList) extends AnyVal {
def asShapeless : HList = list match {
case SHNil => HNil
case HCons(head, tail) => head :: tail.asShapeless
}
}
}
Le problème avec le code ci-dessus est que le type de item
obtenu à partir val item = container.get(1)
est at.Out
et non Long
comme je m'y attendais.
build.sbt
libraryDependencies ++= Seq(
"com.typesafe.slick" % "slick_2.12" % "3.2.1",
"com.chuusai" % "shapeless_2.12" % "2.3.2"
)
Je vois aussi deux erreurs du compilateur
Error:(19, 35) Implicit not found: shapeless.Ops.At[shapeless.HList, shapeless.Succ[shapeless._0]]. You requested to access an element at the position shapeless.Succ[shapeless._0], but the HList shapeless.HList is too short.
val item : Long = container.get(1)
Error:(19, 35) not enough arguments for method get: (implicit at: shapeless.ops.hlist.At[shapeless.HList,shapeless.Succ[shapeless._0]])at.Out.
Unspecified value parameter at.
val item : Long = container.get(1)
Merci ce qui est excellent. J'ai combiné votre solution avec l'autre lien. mais j'ai toujours un problème. J'ai mis à jour ma question ci-dessus. –
Le problème est que sur le hlist shapeless si je fais un 'container.get (1)' le type de retour est de type 'at.Out' et non Long –