В ответ на ваш первый вопрос о переменных и второй вопрос об операторах if.
Вы не можете изменить значение переменной (глупое имя не так, учитывая, что они не меняются!).
Волшебная пыльца пикси для использования XQuery с любой сложной логикой (и что-то вроде изменяемых переменных) - это рекурсия.
Роберт Харви упомянул языковую конструкцию цикла for, в которой переменная меняет каждыйвремя, которое очень важно, но которое не всегда может решить ваши проблемы, если ваше намеченное поведение не может быть достигнуто простой итерацией списка.То, что вы просили, это изменяемые переменные.
С помощью рекурсии ваши функции вызывают себя.Это означает, что они могут передать измененное значение следующему вызову функции вместо значения, которое они уже имеют.Он более или менее дополняет изменчивую переменную, но позволяет сохранить преимущества функционального языка.
Может быть немного сложным переключиться с процедурного (последовательного выполнения шагов) способа мышленияк функциональному (одновременному оцениванию предложений) образу мышления.
Рекурсия позволяет предложениям, которые фактически оцениваются, зависеть от сложной логики, которая выглядит последовательной.На практике вы просто создаете предложения, которые требуют, чтобы другие оценивали, прежде чем они смогут оценить себя, что не совсем то же самое.
Вот глупый, совершенно неактуальный и полностью непроверенный пример, который показывает, как работает списокможет быть изменен «на лету», так как он проходит через рекурсию, что невозможно в цикле for.
Обратите внимание, что переменная $ patternremaining является строго новой переменной (рассчитанной частично на основе $ pattern).Независимо от того, какие шаблоны передаются в качестве аргумента в рекурсивный вызов, они присваиваются $ шаблонам в рамках нового вызова функции.
(: Here $patterns looks like <pattern match="something" replace="else" /> :)
declare function local:transform($text as text(), $patterns as element(pattern)*) {
if(not($patterns)) then
$text
else
let $patternsremaining := $patterns[position() > 1],
$modifiedtext := replace($text, $pattern/@match, $pattern/@replace)
return
if($local:language="French" and not($patterns[@match='le'])) then (
local:transform($modifiedtext, ($patternsremaining, <pattern match="Londres" replace="London" />))
)
else(
local:transform($modifiedtext, $patternsremaining)
)
};
Для жестких действий с XSLT и XQuery (например, написание компиляторов) рекурсия является единственной моделью I 'нашел с достаточной силой.Реальные примеры имеют тенденцию выглядеть даже сложнее, чем приведенный выше.
Что касается оператора if () then () else (), потому что вполне возможно, что тот же контекст выполнения (если выпроцедурный кодер думает, что «комбинация переменных стека») встречалась ранее, и это же выражение было вычислено уже где-то еще, тогда оператор if НИКОГДА не будет вычисляться снова, потому что интерпретатор может кэшировать результат, основываясь на предыдущем вызове.Поэтому не совсем верно, что вы можете положиться на последовательность.Он может вообще не запускаться!
Это возможно, поскольку в определение языка встроено отсутствие побочных эффектов, которые могли бы изменить результат функциональной оценки (следовательно, те переменные, которые не меняются).
Эта кешируемость является центральной особенностью функционального подхода.Это создает потенциал для написания высокоэффективных интерпретаторов, но требует от вас рекурсивного мышления, если вы хотите работать с изменяемыми значениями.