2015-11-21 3 views
1

Функциональных программисты научили нас неизменность über Alles и, таким образом, чтобы объявить все поля, как Вал ов кроме вара с. Лично я также хотел бы обеспечить постоянство поля с помощью компилятора. Но как вы инициализируете эти поля во время пользовательской десериализации?Неизменность и пользовательская десериализация в Scala

Я проверил, система десериализации отлично обновить константы

case class S(value: String) extends Serializable { 

    private def writeObject(out: ObjectOutputStream) = out.defaultWriteObject() 

    private def readObject(in: ObjectInputStream) { 
     println("restoring " + this) // restoring S(null) 
     in.defaultReadObject() 
     println("restored to " + this) // restored S(string 1) 
    } 


} 

, тогда как я не могу ручное ее закрытие сделать то же самое

case class I(value: Int) extends Serializable { 

    private def readObject(in: ObjectInputStream) { 
     value = in.readInt() // compilation error "reassignment to val" 
    } 

} 
+1

Если вам нужно настроить сериализацию java по умолчанию, вы, вероятно, должны сделать сериализуемый конструктор. Концепция Builder является общей для ООП и FP и может служить мостом. – Odomontois

ответ

1

Одно слово: отражение. В частности, отражение Java. Отражение Java ничего не знает о семантике Scala, поэтому он с радостью позволит вам делать вещи, которые запрещены в Scala. Фактически, система отражения Java небезопасна, она даже позволит вам делать вещи, которые запрещены на Java!

Если вы посмотрите на the source code for Serializable, вы увидите, что он фактически пуст. И просто полагается на сериализацию Java.

(На самом деле, в некоторых случаях, вам не нужно даже отражение нарушить семантику в Scala. Java счастливо позволит вам расширить sealed признак или класс, потому что Java не знает о sealed.)

+0

Согласно моему опыту, java-отражение не знает о Java-идентификаторах. Вы должны вводить имена полей/mehtod в виде строк, которые не проверяются компилятором и не синхронизируются с базой кода как перо на ветру. Возможно, вы имели в виду другое отражение, но я не вижу, потому что ссылка сломана. –

+0

Вот бегущая демонстрация с отражением http://scastie.org/13233 - 6 строк кода + соответствующие накладные расходы времени исполнения. Кажется, что переквалификация valval => var дешевле :) –

+0

@ValentinTihomirov эта ссылка не работает. Что именно должно выглядеть реализация readObject? –

Смежные вопросы