Я пишу код для исследования PhD и начинаю использовать Scala. Мне часто приходится обрабатывать текст. Я привык к Python, чья формулировка "yield" чрезвычайно полезна для реализации сложных итераторов в больших, часто нерегулярно структурированных текстовых файлах. Подобные конструкции существуют на других языках (например, С#) по уважительной причине.
Да, я знаю, что на этом были предыдущие потоки. Но они выглядят как взломанные (или, по крайней мере, плохо объясненные) решения, которые явно не работают хорошо и часто имеют неясные ограничения. Я хотел бы написать код примерно так:
import generator._
def yield_values(file:String) = {
generate {
for (x <- Source.fromFile(file).getLines()) {
# Scala is already using the 'yield' keyword.
give("something")
for (field <- ":".r.split(x)) {
if (field contains "/") {
for (subfield <- "/".r.split(field)) { give(subfield) }
} else {
// Scala has no 'continue'. IMO that should be considered
// a bug in Scala.
// Preferred: if (field.startsWith("#")) continue
// Actual: Need to indent all following code
if (!field.startsWith("#")) {
val some_calculation = { ... do some more stuff here ... }
if (some_calculation && field.startsWith("r")) {
give("r")
give(field.slice(1))
} else {
// Typically there will be a good deal more code here to handle different cases
give(field)
}
}
}
}
}
}
}
Я хотел бы увидеть код, который реализует функции generate() и give(). BTW give() следует назвать yield(), но Scala уже выбрал это ключевое слово.
Я понимаю, что по причинам, которые я не понимаю, Scala продолжения могут не работать внутри оператора for. Если это так, generate() должен предоставить эквивалентную функцию, которая работает как можно ближе к оператору for, потому что код итератора с выходом почти неизбежно находится внутри цикла for.
Пожалуйста, я бы предпочел не получать ни одного из следующих ответов:
- 'yield' отстой, продолжения лучше. (Да, в общем, вы можете делать больше с продолжениями, но они хладны трудно понять, и 99% времени итератор - это все, что вам нужно или нужно. Если Scala предоставляет множество мощных инструментов, но они слишком сложны для использования на практике, язык не будет успешным.)
- Это дубликат. (См. Мои комментарии выше.)
- Вы должны переписать свой код с помощью потоков, продолжений, рекурсии и т.д. и т.д. (см. № 1. Я также добавлю, технически вам также не нужны петли. В этом отношении технически вы можете делать абсолютно все вам когда-либо понадобится Комбайны SKI.)
- Ваша функция слишком длинная. Разбейте его на мелкие кусочки, и вам не понадобится "урожай". Так или иначе, вы должны сделать это в производственном коде. (Во-первых, "вам не нужно" урожайность ", в любом случае сомнительна. Во-вторых, это не производственный код. В-третьих, для обработки текста, как это, очень часто, разбивая функцию на более мелкие части, особенно когда язык заставляет делать это, потому что ему не хватает полезных конструкций - только делает код более сложным для понимания.)
- Перепишите код с переданной функцией. (Технически, да, вы можете это сделать. Но результат больше не является итератором, а целые итераторы гораздо приятнее, чем функции цепочки. В общем, язык не должен заставлять меня пишите в неестественном стиле - конечно, создатели Scala верят в это вообще, поскольку они обеспечивают shitloads синтаксического сахара.)
- Перепишите свой код в этом, в том или ином виде, или в другом прохладном, удивительном способе, о котором я только что подумал.