ドキュメントは言う
Juliaでは、関数へのすべての引数は参照によって渡されます。
したがって、これら2つの関数の動作の違いを見て非常に驚きました。
function foo!(r::Array{Int64})
r=r+1
end
function foobar!(r::Array{Int64})
for i=1:length(r)
r[i]=r[i]+1
end
end
予想外に異なる出力は次のとおりです。
Julia> myarray
2-element Array{Int64,1}:
0
0
Julia> foo!(myarray);
Julia> myarray
2-element Array{Int64,1}:
0
0
Julia> foobar!(myarray);
Julia> myarray
2-element Array{Int64,1}:
1
1
配列が参照によって渡された場合、私はfooを期待していました!ゼロを1に変更します。
r=r+1
はAssignmentステートメントです。これは、r
を再割り当てすることを意味するため、親スコープ内のペアを参照しなくなります。だが r[i]=r[i]+1
Mutatesr値、突然変異は割り当てとは異なります( ここでの適切な説明 )、その後r
は、親スコープ内のペア変数を引き続き参照します。
ここの文書は少し曖昧だと思います。
厳密に言えば、Juliaは、Python、Java、Ruby、jsなどのほとんどの言語で使用される「値による呼び出し」または「共有による呼び出し」です...を参照してください wiki
参照動作による呼び出しは、実際にfoo!
ゼロを1に変更します。ただし、ジュリアはそれをサポートしていません。 (C#を知っている場合は、それがref
またはout
の機能です)
配列内の各変数を変更するために、ブロードキャスト.
操作が使用できます。ただし、配列内の各値は等しく変更されるため、for
ループは必要ないことに注意してください。
配列の各要素に1を追加する場合:
a = Rand(1:10, 10)
show(a) = [4, 8, 9, 1, 4, 2, 6, 7, 1, 5]
function add1!(a::Array{Int64})
a .= a .+ 1
end
add1!(a);
show(a) = [5, 9, 10, 2, 5, 3, 7, 8, 2, 6]
それにもかかわらず、配列の各値を個別に変更する必要がある場合は、インデックスを使用したfor
ループが避けられません。
実際には、前の回答で説明した理論(call _by sharing
_)に関係なく、配列としてのポインター変数が_by reference
_を渡され、数値などのスカラー変数が_by value
_。
これは、パラメーターが_by value
_または_by reference
_の場合、関数宣言の正式なパラメーター部分で指定するCまたはPascal言語に慣れている私のような人々にとっては苦痛です。
ただし、関数で複数の値を返すことができるJuliaの機能により、スカラー変数のパラメーター_by reference
_をシミュレートする洗練された方法があります。変数が再作成されるため、これは文字列などの不変の変数に対しても機能することは明らかです。
ジュリアのコード
_function process(a,b,c)
a += c
b *= c
return a*b*c, a, b # normal result, changing "a" and "b"
end
a = 4
b = 7
println("Before: ", a," ",b)
result, a, b = process(a,b,7)
println("After: ", a," ",b," ", result)
_
表示
_Before: 4 7
After: 11 49 3773
_
a
とb
は両方とも関数プロセス内で変更されました。 a
が7に追加され、b
に7が掛けられました