使用しているjsonシリアライゼーションライブラリを実際に指定する必要がありますが、次のことを行うだけで機能することがほぼ保証されています。
case class Asset(id: Option[Int], description: Option[String]= None, url = "images/" + id.toString+".png")
とにかくデフォルト値があるとすれば、url
それをパラメーターに変えてもコードに悪影響を与えることはありません (Asset(None)
以前のように、例によって行うことができます)。唯一の欠点は、クライアント コードがAsset
に対して異なる値を持つインスタンスを作成するurl
可能性があることです。
その場合、おそらくAsset
クラス用のカスタム json 形式を作成する必要がありますが、どのシリアル化ライブラリを使用しているかを知らなければ、この点でこれ以上のことはできません。
更新:
url
おっと、のデフォルト値が別のパラメータに依存するという事実を完全に見逃していました( id
)(気づいてくれた@Kristian Domagalaに感謝します)。したがって、上記のスニペットはコンパイルされません。簡単な解決策の 1 つはurl
、@Kristian Domagala が提案するように、2 番目のパラメータ リストを追加することです。
case class Asset(id:Option[Int],description:Option[String]=None)(val url:String = "images/" + id.toString+".png")
Asset
しかし、これは(url
インスタンスを比較するときに考慮されなくなった)の等値セマンティクスを変更し、構築構文も変更するため、理想的ではない可能性があります: 値を明示的に指定する場合は、例ではなく次のurl
ようにする必要があります。. これらの欠点に耐えることができる場合、これは確かに最も簡単な解決策です.Asset(Some(123))("gfx/myImage.png")
Asset(Some(123), url="gfx/myImage.png")
Asset.apply
それ以外の場合は、別の回避策があります。 (手動で) 自分自身を再定義できます。
case class AssetImpl( val id: Option[Int], val description: Option[String], val url: Option[String]) {
override def productPrefix = "Asset"
}
type Asset = AssetImpl
object Asset {
def apply( id: Option[Int], description: Option[String] = None, url: Option[String] = None ) = {
new Asset( id, description, url.orElse( id.map( "images/" + _ + ".png") ) )
}
}
ご覧のとおり、 のデフォルト値を持つ に変わりurl
ました(以前のコンパイル エラーを回避します。これは、もはや依存しないためです)。の) の.Option
None
id
def apply...
Asset
url
id
id.map( "images/" + _ + ".png")
残りは基本的に、再定義できるノイズにすぎAsset.apply
ません。実際には、ケース クラスのファクトリを再定義することはできません (別のオーバーロードを追加することしかできません)。そこで、クラスの名前を に変更しAssetImpl
、タイプ エイリアスを追加して、誰も気付かないように ( ;-) )、メソッドAsset
を定義する独自のオブジェクトを作成しました (これは、自動生成されたメソッドapply
と競合しなくなりました。apply
単純に標準クラス (非ケース クラス) に変更するAssetImpl
こともできますが、再定義する必要があり、クラスにフィールドを追加/削除するときに維持する必要があることを考えると、より面倒です。Asset
equals
hashCode