私は何とかコンパイル時に、caseクラスのフィールドの名前をval(おそらくシングルトン型の文字列かシンボルか)で取得したいと考えています。次のようなケースレットフィールドの名前を文字列/シンボルとして取得するには、シェイプレスを使用してコンパイル時に?
何か:
import shapeless._
case class MyClass(field1: String, field2: Int)
val field1Lens = lens[MyClass] >> 'field1
// val name = field1Lens.name // it should be "field1", aka 'field1.name
私は必ずしもレンズを使用する必要はありません、働く任意の技術は、(LabelledGeneric
で何か?)大丈夫です。私は別にそれを指定することなく、ケースクラスフィールドの名前を得ることができるものを持っていたいと思います。このようにして、クラス内のfield1
メンバーの名前をリファクタリングすると、それに応じてname
が変更されます。
:
val name = 'field1
val field1Lens = lens[MyClass] >> name // can't possibly work
は私がlens[MyClass] >> name.narrow
を試してみましたが、それは
このいずれかを動作しません。私は現在やっているし、もちろん、私はそれを好きではない:
// If I change the name of the field, compilation fails
// and I'm forced to check this line of code so I can change the string in the line below
protected val fieldNameCheck = lens[X].someField
val someField = "someField"
編集:[OK]を、私はgabrieleの質問を見た、と0を使用して、レコードの(タグ付き)キーを含むHListを取得できます。 私が必要とするのは、特定のフィールドを1つだけ取得することです。すべてのフィールドを含むリストではありません。
私は特定のキーを取得するためにselect
を使用しようとしているが、私は、[OK]をこれまでのところ、私はそれが働いてしまったトラヴィスのコメントのおかげ
import shapeless._
import shapeless.syntax.singleton._
import shapeless.ops.record._
case class Foo(bar: String, baz: Boolean)
val labl = LabelledGeneric[Foo]
val keys = Keys[labl.Repr].apply
// the following doesn't work
// val bar = 'bar.narrow
// keys.select[bar.type]
// keys.get('bar)
[LabelledGenericインスタンスからのラベル値の抽出]の可能な複製(http://stackoverflow.com/questions/27434302/extract-label-values-from-a-labelledgeneric-instance) –
私は理解しているとは思わない動機づけ - それはあなたが別の場所にそれを書く必要がないように、あなたのコードの1つの場所にリテラル '' bar 'を書きたいと思うように聞こえ、リファクタリングでどのように役立つか分かりません。メンバ名の変更が心配な場合は、位置セレクタを使用する方が良いでしょう。 –
短いストーリー:シリアライズライブラリ。私はカスタム・シリアライザを書く必要がありません。ライブラリーが何をしているか(フィールド名をキーとして使用してjsonオブジェクトを作成するなど)、フィールドの名前を別の場所に置く必要があるからです弾性サーチ上)。私はリテラル 'バーを一度書くだけですが、ケースクラスが変更されてもコードはコンパイルされます。私が必要とする各 '' bar'には、全く同じ名前の '(bar:T)' caseクラスのパラメータがあることを確認するためにたくさんのテストが必要です。 –