Задача
У меня есть такой код
var ls = src.iter.toList
src.iter = ls.iterator
(это часть конструктора копирования моего итератора-обертки), который читает исходный итератор и в следующей строке устанавливает его обратно. Проблема в том, что эти две строки должны быть атомарными (особенно если учесть, что я меняю источник конструктора копирования - мне это не нравится, но хорошо ...).
Я читал об актерах, но не вижу, как они здесь подходят - они больше похожи на механизм асинхронного выполнения. Я читал о решениях Java и их использовании в Scala, например: http://naedyr.blogspot.com/2011/03/atomic-scala.html
Мой вопрос: какой самый Scala способ сделать некоторые операции атомарными? Я не хочу использовать для этого тяжелую артиллерию, а также не хотел бы использовать какие-то внешние ресурсы. Другими словами - то, что выглядит и чувствует себя «правильно».
Мне нравится решение, представленное в приведенной выше ссылке, потому что именно это я и делаю - обмениваюсь ссылками. И если я правильно понимаю, я бы охранял только эти 2 строки, и другой код не должен быть изменен! Но я буду ждать окончательного ответа.
Фон
Потому что на каждый N-й вопрос вместо ответа я читаю «но зачем вы используете ...» здесь:
Как скопировать итератор в Scala? : -)
Мне нужно скопировать итератор (сделать разветвление), и такое решение является наиболее "правильным", о котором я читал. Проблема в том, что он уничтожает оригинальный итератор.
Решения
Замки
Например, здесь:
http://www.ibm.com/developerworks/java/library/j-scala02049/index.html
Единственная проблема, которую я вижу здесь, это то, что я должен поставить блокировку на эти две строки, и любое другое использование на iter. Сейчас это мелочь, но когда я добавляю некоторый код, легко забыть добавить дополнительную блокировку.
Я не говорю «нет», но у меня нет опыта, поэтому я хотел бы получить ответ от кого-то, кто знаком со Scala, указать направление - какое решение является лучшим для такой задачи, и в долгосрочной перспективе -run.
Неизменяемый итератор
Хотя я ценю объяснение Paradigmatic, я не понимаю, как такой подход подходит для моей проблемы. Дело в том, что класс IteratorWrapper должен обернуть итератор - то есть необработанный итератор должен быть скрыт внутри класса (обычно это делается путем его приватности). Такие методы, как hasNext () и next () также должны быть упакованы. Обычно next () изменяет состояние объекта (итератора), поэтому в случае неизменяемого IteratorWrapper он должен возвращать как новый IteratorWrapper, так и состояние next () (успешно или нет). Другим решением было бы возвращать NULL, если raw next () не работает, в любом случае это делает использование IteratorWrapper не очень удобным.
Хуже того, до сих пор не существует простого способа скопировать такой IteratorWrapper.
Так что или я что-то упускаю, или на самом деле классический подход к созданию атомарного куска кода чище. Поскольку вся нагрузка содержится внутри класса, и пользователю не нужно платить цену за то, как IteratorWrapper обрабатывает данные (в данном случае необработанный итератор).