Как сделать атомарный обмен - способ Scala?

Проблема

У меня есть такой код

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, чтобы указать направление - какое решение лучше всего для такой задачи, и в долгосрочной перспективе -запустить.

Неизменяемый итератор

Хотя я ценю объяснение Paradigmatic, я не понимаю, как такой подход подходит для моей проблемы. Дело в том, что класс IteratorWrapper должен обернуть итератор - т.е. необработанный итератор должен быть скрыт внутри класса (обычно это делается путем его приватности). Такие методы, как hasNext () и next (), также должны быть обернуты. Обычно next () изменяет состояние объекта (итератора), поэтому в случае неизменяемого IteratorWrapper он должен возвращать как новый IteratorWrapper, так и статус next () (успешно или нет). Другое решение - вернуть NULL, если raw next () не работает, в любом случае это делает использование такого IteratorWrapper не очень удобным.

Хуже того, до сих пор нет простого способа скопировать такой IteratorWrapper.

Так что либо я что-то упускаю, либо на самом деле классический подход к созданию атомарного фрагмента кода чище. Потому что вся нагрузка содержится внутри класса, и пользователю не нужно платить за то, как IteratorWrapper обрабатывает данные (в данном случае необработанный итератор).

5
задан Community 23 May 2017 в 09:59
поделиться

0 ответов

Другие вопросы по тегам:

Похожие вопросы: