結合

2014-07-10 55 views
1

之前變換ANORM(播放框架)值,我有我的代表域的情況下類:結合

case class MyModel(rawValue: String, transformedValue: String) 

rawValue映射到數據庫中的值,正確分析和綁定。我正在嘗試的是將transformedValue添加到我的模型中:該值僅僅是我對rawValue執行的任意轉換。它不會映射到數據庫/查詢中的任何數據。

我有一個解析器(前要添加transformedValue),看起來像這樣:

val parser = { 
    get[String]("rawValue") map { 
    case rawValue => MyModel(rawValue) 
    } 
} 

由於MyModel是immutible及其創建後我不能插入transformedValue進去,哪些地方是最好的方法來做和添加這種轉換(例如添加專門的值到模型)最好不使用變量?

來自Java,我可能只是將getTransformedValue獲得者添加到對rawValue屬性執行此轉換的域類。

回答

2

由於transformedValue似乎是派生屬性,並且不是構造函數中提供的內容,所以可以將其定義爲函數體中的屬性,可能使用lazy限定符,以便僅根據需要進行計算(例如只有一次):

case class MyModel(rawValue: String) { 
    lazy val transformedValue: String = { 
    // Transformation logic, e.g. 
    rawValue.toLowerCase() 
    } 
} 

val定義時評估;在調用時評估def。 A lazy val在首次訪問時進行評估。

在很少需要的昂貴計算或者邏輯需要時使用lazy可能是合適的。但是在大多數情況下,應該使用常規valQuoting

懶val爲免費的(甚至便宜)。只有當你絕對需要懶惰才能正確使用它,而不是爲了優化。

+0

謝謝。這看起來像我在看到這個之前發佈的解決方案。我喜歡使用'懶惰'的想法。你可以通過使用val而不是def來評論差異(就像我在解決方案中那樣)? – oym

+0

'val'在定義時被評估;調用時會評估「def」。當第一次訪問時,會評估一個「懶惰的val」。請參閱http://stackoverflow.com/a/7484933/376366 –

+0

有關何時使用lazy val而不是val的說明,請參閱已更新的答案。 –

1

我不明白爲什麼你不只是做了改造解析器本身:

def transformation(rawValue: String): String = ... 

val parser = { 
    get[String]("rawValue") map { 
     case rawValue => MyModel(rawValue, transformation(rawValue)) 
    } 
} 

或者,如果你不想因爲某種原因做在那裏,你可以使用copy來創建MyModel新副本新值:

val model = MyModel("value", ..) 

val modelWithTransform = model.copy(transformedValue = transformation(model.rawValue)) 

你也可以重載apply的同伴對象中自動應用的轉變:

case class MyModel(rawValue: String, transformedValue: String) 

object MyModel { 

    def apply(value: String): MyModel = MyModel(rawValue, transformation(rawValue)) 

    val parser = { 
     get[String]("rawValue") map { 
      case rawValue => MyModel(rawValue) 
     } 
    } 
} 

MyModel可能是不可變的,但是您隨時可以創建另一個副本並更改一些值。

+0

感謝您的意見。在我看到這個之前,我添加了我的解決方案,並且會比較你的意見。你的解決方案似乎有點複雜 – oym

+0

@oym不是真的,只是利用了一些語法糖。使用這種方法,您只會執行一次計算,並且只要解析它就可以使用。 –

0

原來它比我想象的要簡單和解決方案都看起來像什麼,我說我會在Java中已經做了:

我只需要添加一個函數來爲MyModel,做這樣的轉換:

case class MyModel(rawValue: String) { 
    def transformedValue = { 
    // do the transformation here and return it 
    } 
} 
+0

這將在每次引用時計算轉換。要做到這一點,請參閱我的答案。 –

+0

哦,我明白了。你不能在def上添加'lazy'。只有一個val。 – oym