Я новичок в метапрограммировании, так что, возможно, я не понимаю этого. Я думал, что цель макроса @nloops
в Base.Cartesian
состоит в том, чтобы сделать возможным кодирование произвольного числа вложенных циклов в условиях, когда размерность априори неизвестна. В документации к модулю приведен следующий пример:
@nloops 3 i A begin
s += @nref 3 A i
end
, что оценивается как
for i_3 = 1:size(A,3)
for i_2 = 1:size(A,2)
for i_1 = 1:size(A,1)
s += A[i_1,i_2,i_3]
end
end
end
Здесь число 3 известно априори. Однако для моих целей и для целей, которые, как я думал, был создан nloops, число вложенных уровней заранее неизвестно. Поэтому я не смог бы жестко закодировать целое число 3. Даже в документации указано:
(основной) синтаксис @nloops выглядит следующим образом:
- Первый аргумент должен быть целым числом (а не переменной), определяющим количество циклов.
...
Если я назначу целочисленное значение - скажем, размерность массива, который передается в функцию - какой-то переменной, макрос nloops больше не работает:
b = 3
@nloops b i A begin
s += @nref b A i
end
Возвращает ошибку:
ERROR: LoadError: MethodError: no method matching _nloops(::Symbol, ::Symbol, ::Symbol, ::Expr)
Closest candidates are:
_nloops(::Int64, ::Symbol, ::Symbol, ::Expr...) at cartesian.jl:43
...
Я не знаю, как nloops оценивает переменную b
как целое число, а не как символ. Я просмотрел документацию и попробовал различные итерации eval
и других функций и макросов, но он либо интерпретируется как символ, либо Expr
. Как правильно, юлианский способ написать это?