Estou migrando o código que costumava usar a reflexão Scala 2.
Estou tentando usar a biblioteca de reflexão scala .
Preciso obter o valor de um campo de um determinado nome de uma classe de caso.
Exemplo:
$ scala-cli -j system -S 3.4.2 --dep co.blocke::scala-reflection:2.0.8
scala> import co.blocke.scala_reflection.RType
scala> case class A(a: Int, b: String)
// defined case class A
scala> import co.blocke.scala_reflection.rtypes.ScalaClassRType
scala> val t = RType.of[A].asInstanceOf[ScalaClassRType[A]]
val t: co.blocke.scala_reflection.rtypes.ScalaClassRType[A] = ScalaClassRType(rs$line$2$A,rs$line$2$.A,List(),List(),List(),List(ScalaFieldInfo(0,a,IntRType(),Map(),None,None,false), ScalaFieldInfo(1,b,StringRType(),Map(),None,None,false)),Map(),List(java.lang.Object, scala.Product, java.io.Serializable),false,false,true,false,Map(),List(),List(),false)
scala> t.fields.find(_.name == "a")
val res2: Option[co.blocke.scala_reflection.rtypes.FieldInfo] = Some(ScalaFieldInfo(0,a,IntRType(),Map(),None,None,false))
scala> val c = A(3,"hola")
val c: A = A(3,hola)
Neste exemplo, como posso obter o valor de field a
por reflexão em instance c
.
Se for mais fácil, eu poderia considerar usar outras bibliotecas como izumi-reflect .
Supondo que você queira serializar as coisas colocando-as no JDBC, um campo após o outro:
este é um esboço que usarei como algo que você distribuirá para chamar alguma API.
Esta será a classe de tipo que pegaria o valor
A
e de alguma forma colocaria todos os seus dadosSerializationTarget
- como quer que seja.Começaremos com algumas instâncias (stub) mostrando como os primitivos podem ser tratados:
Agora, quando ligaríamos
o código escolheria o certo
given
e o usaria, basicamente como um padrão de estratégia, mas a estratégia é editada com base em um tipo.Finalmente, usaríamos
Mirror
s para gerar tal estratégia para cadacase class
:Finalmente, podemos chamá-lo de:
Isso criaria uma nova instância
SerializeForJDBC[Example]
sempre que necessário. Não deve ser um grande problema, mas se quisermos armazenar a instância em cache, podemos usar aderives
palavra-chave (já que definimos o método baseado em espelho comoderived
):Em seu código real, você teria que substituir
SerializationTarget
a forma como interage com o JDBC, substituir os corpos dos primitivosgiven
e ajustar como você combinaria as instâncias de cada campo em uma instância de um wholecase class
.Uma alternativa aos Mirrors integrados é a biblioteca Magnolia - por ser baseada em macro, é capaz de fornecer mensagens de erro um pouco melhores do que implícitos/dados ausentes. Também é uma boa escolha se quisermos ter uma solução compilada cruzada entre Scala 2 e Scala 3.