Имеет ли значение, где стоит сдвиг в блоке сброса?

Предположим, есть блок reset с одним shift:

val r = reset { 
   // do smth. 1
   shift {...}
   // do smth. 2
   // do smth. 3
}

Правильно ли я ставлю shift после "сделать что-то 2" или "сделать что-то 3" без изменения результата r? Правильно ли, что не имеет значения, где находится shift в блоке reset?


person Michael    schedule 30.05.2011    source источник


Ответы (2)


Это сильно зависит от того, что вы делаете в shift. Если вы просто вызываете предоставленную функцию следующим образом: shift((k: Unit => Unit) => k(Unit)), то в вашем конкретном примере действительно не имеет значения, где стоит shift.

Функция Shift просто захватывает код, который следует за ней в другой функции (в моем примере эта функция называется k). Другими словами, этот код:

val r = reset { 
   // do smth. 1
   shift((k: Unit => Unit) => k(Unit))
   // do smth. 2
   // do smth. 3
}

будет переписан компилятором примерно так (этот код просто демонстрирует общую идею и не должен показывать, что на самом деле сгенерирует плагин компилятора):

val k = (Unit => Unit) => {
    // do smth. 2
    // do smth. 3
} 

val r = { 
   // do smth. 1
   k(Unit)
}

Но если у вас есть какая-то логика внутри shift, например условное k выполнение, то действительно имеет значение, где находится этот shift.

Надеюсь, это поможет (и я надеюсь, что правильно понял ваш вопрос)

person tenshi    schedule 30.05.2011

Просто добавив к уже данному ответу, место, где вы МОЖЕТЕ перемещаться по shift, заключается в том, иметь ли код перед сдвигом или иметь его внутри функции, которую вы передаете shift:

reset { 
  foo(); bar();
  shift { k => stuff }
  baz()
}

такой же как

reset {
  foo();
  shift { k => bar(); stuff }
  baz()
}
person hzap    schedule 31.05.2011