Scala - Получить строковое представление имени свойства объекта, а не значения, для сравнения - PullRequest
0 голосов
/ 23 января 2020

Я хочу получить строковое представление имени свойства объекта, а не значения свойства, чтобы я мог сравнить его со значением переменной внутри условного оператора.

case class CustomObj(name: T)
case class PropertyObj(property: String)

val custObj = CustomObj("Chris")
val propObj = PropertyObj("name")

if(propObj.property.equals(custObj. /* the property name as a String, so "name", not the value ("Chris"*/)) {
    // do something
}

Как получить доступ к тому, что по сути является ключом свойства в CustomObj?

Ответы [ 2 ]

4 голосов
/ 23 января 2020

Я предполагаю, что вы не знаете тип custObj во время компиляции. Тогда вам придется использовать отражение во время выполнения в Scala 2.12.

scala> case class CustomObj(name: String)
defined class CustomObj

scala> val custObj: Any = CustomObj("Chris")
custObj: Any = CustomObj(Chris)

scala> import scala.reflect.runtime.currentMirror
import scala.reflect.runtime.currentMirror

scala> val sym = currentMirror.classSymbol(custObj.getClass)
sym: reflect.runtime.universe.ClassSymbol = class CustomObj

scala> val props = sym.info.members.collect{ case m if m.isMethod && m.asMethod.isCaseAccessor => m.name.toString }
props: Iterable[String] = List(name)

scala> if (props.exists(_ == "name")) println("ok")
ok
4 голосов
/ 23 января 2020

Попробуйте productElementNames вроде так

case class CustomObj(name: String)
case class PropertyObj(property: String)

val custObj = CustomObj("Chris")
val propObj = PropertyObj("name")

if (custObj.productElementNames.toList.headOption.contains(propObj.property)) { ... } else { ... }

Обращаясь к комментарию, основываясь на Krzysztof , попробуйте бесформенное решение

import shapeless._
import shapeless.ops.record._

def firstPropertyNameOf[P <: Product, L <: HList](p: P)(implicit
    gen: LabelledGeneric.Aux[P, L],
    toMap: ToMap[L]): Option[String] = {
  toMap(gen.to(p)).map{ case (k: Symbol, _) => k.name }.toList.headOption
}

firstPropertyNameOf(custObj).contains(propObj.property)   // res1: Boolean = true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...