首页 > 解决方案 > Julia,在函数中使用 @views 的语法

问题描述

我想构建一个函数,它遍历 Julia“zip”文件的值并替换大型 3d 数组中的一些值。在以前的帮助中,有人明智地建议使用,@view我非常喜欢写回数组的原始部分而不是制作副本的想法。如果这是一个好方法(乐于接受建议),我无法弄清楚该函数的正确语法,即利用@view. 这是一个演示:

运行良好的原始代码将在最终应用中更多

(@view Pop[end, :, 1])[findall(x -> x==33, Pop[end, :, 1])] .= 3
(@view Pop[end, :, 1])[findall(x -> x==44, Pop[end, :, 1])] .= 4

它只是替换数组中的 33 -> 3 和 44 -> 4Pop[end, :, 1]

所以我生成了 zip 文件:

Orig = [44, 33];
NewS = [4 , 3];
ResetZip = zip(Orig,NewS)

然后产生函数:

## Function to reset status numbers back from 44 and 33 to 4 and 3
function ResetState(Arr1, Orig, NewS)
    Arr1[findall(x -> x==Orig, Arr1)] .= NewS
end

然后尝试迭代地执行函数ResetZip

for (Orig, NewS) = ResetZip
    ResetState(@view (Pop[end, :, 1]), Orig, NewS)
end

但我得到这个错误

ERROR: LoadError: ArgumentError: Invalid use of @view macro: argument must be a reference expression A[...].

所以我的语法有问题。我的问题是,我在哪里@view可以得到正确的语法,能够使用它,并迭代 zip 文件的值?谢谢。Ĵ

标签: functioniterationjulia

解决方案


一般来说,这只是宏解析的一个怪癖。您可以用空格分隔宏的参数,也可以将其视为函数调用。你写过:

ResetState(@view (Pop[end, :, 1]), Orig, NewS)

@view和之间的空格(Pop...意味着您选择了空格分隔的机制。并且宏会很高兴地“吞噬”你想要的所有其他参数ResetState。换句话说,您实际上是将元组传递给@view. 如果我让 Julia 简单地“引用”这个表达式,你可以看到它是如何打印出来的——它使用明确的括号来使它更明显:

julia> quote
         ResetState(@view (Pop[end, :, 1]), Orig, NewS)
       end
quote
    #= REPL[5]:2 =#
    ResetState(#= REPL[5]:2 =# @view((Pop[end, :, 1], Orig, NewS)))
end

修复?每当您在函数调用中使用它时,删除该空间并像函数一样调用宏:

ResetState(@view(Pop[end, :, 1]), Orig, NewS)

推荐阅读