переназначение scala на val в классе опций

Мой код выглядит так:

    case class SRecord(trialId: String, private var _max:Int)    {
      def max=_max 
      def max_=(value:Int):Unit=_max=value
     }

Позже я применяю к нему функцию:

def groupSummaryRecords(it:Iterator[Option[SRecord]],   optionSummary:Option[SRecord]):Option[SRecord] = {
    var max=0;
    var sRecord1 : Option[SRecord] = None 
    var i=0
    while(it.hasNext) {
        var sRecord:Option[SRecord] = it.next();
        if(i==0) {
            sRecord1 = sRecord;
        }
        ..
    }
    sRecord1.max=max; // getting 'reassignment to val' compilation error
    ..
 }

Почему я получаю эту ошибку компиляции и как ее исправить?

Если я вместо этого изменить sRecord и sRecord1 экземпляры быть типа SRecord вместо Option[SRecord], а также подпись метода, все это работает отлично однако.

Но в некоторых случаях у меня может быть null SRecord, поэтому я использую None/Some. Я новичок в Scala, использование Option/Some повсюду кажется настоящей болью, если вы спросите меня, я просто думаю об удалении всей этой Option ерунды и тестировании на «null» в старой доброй Java, по крайней мере, мой код будет работать ?? !


person matthieu lieber    schedule 18.12.2015    source источник
comment
что ты здесь делаешь?   -  person Rob Starling    schedule 18.12.2015
comment
общий совет: избегайте классов case с изменяемым состоянием (vars) - просто сделайте его обычным классом, если вы действительно не хотите выполнять с ним сопоставление с образцом.   -  person Rob Starling    schedule 18.12.2015
comment
Не используйте null. Возможно, чтение этой статьи поможет вам решить проблемы, с которыми вы сталкиваетесь при использовании Option danielwestheide.com/blog/2012/12/19/   -  person Jens Schauder    schedule 18.12.2015
comment
спасибо, я уже прочитал статью, но это не помогло в этом вопросе ..; Хорошо, @RobStarling, я думал, что использование класса case автоматически определит мои методы получения, так что это было бы полезно.   -  person matthieu lieber    schedule 18.12.2015
comment
@matthieulieber это правда, что вы получите это приятное преимущество, но вы также получите странные побочные эффекты, такие как == сравнения, которые игнорируют изменяемые биты.   -  person Rob Starling    schedule 18.12.2015
comment
например учитывая case class A(x: Int, y: Int) { var _z: Int = 0; def z=_z; def z_=(z: Int):Unit=_z=z };, val a=A(1,2) и val b=A(1,2), тогда a==b будет true, даже если вы измените один из их z, например a.z=7.   -  person Rob Starling    schedule 18.12.2015
comment
для простого, полностью общедоступного, изменяемого контейнера, такого как C struct, вы, вероятно, просто захотите class B(var x: Int, var y: Int);   -  person Rob Starling    schedule 18.12.2015
comment
спасибо за объяснение @RobStarling!   -  person matthieu lieber    schedule 19.12.2015


Ответы (1)


В строке sRecord1.max=max вы пытаетесь вызвать метод max для Option[SRecord], а не для SRecord. Вы хотите получить доступ к содержащемуся SRecord (если есть) и вызвать метод для этого, что можно сделать с помощью foreach:

sRecord1.foreach(_.max=max)

который десахарируется:

sRecord1.foreach( srec => srec.max=max )

(фактическое имя "srec" составлено, компилятор присвоит какое-то внутреннее имя, но вы поняли идею). Если sRecord1 равно None, это ничего не сделает, но если Some(srec), выполнение метода будет передано для работы с содержащимся в нем экземпляром.

person Shadowlands    schedule 18.12.2015