84112


このコードではリストを引数に入れたaFunc関数でaの値が更新されますが、intを引数に入れたbFunc関数でbの値が更新されません。これはなぜでしょうか？

また、returnで返すやり方や、bの引数を削除する以外でbの値を更新するやり方はありませんか？アドバイスあればお願いします。

[code]

    final a = [1];
    var b = 1;
    void aFunc(List<int> a_arg){
    //  a.first = 3;
      a_arg[0] = 3;
    }
    
    void bFunc(int b_arg){
      b_arg = 3;
    }
    
    void main() {
      aFunc(a);
      print(a); // [3]
      bFunc(b); 
      print(b); // 1
    }
    
[/code]


CC BY-SA 4.0
2021-12-13T10:36:09.940
84107
2021-12-16T22:01:14.253
2021-12-16T22:01:14.253
36424
36424
question
flutter dart
関数に引数を入れた場合、リスト型なら更新されるが、int型だとなぜか更新されない。


イメージとしては、引数に渡したオブジェクトは関数で使われる際に新しくコピーされているように考えてください。その上で、引数として渡しているオブジェクトが、データそのものなのか、データの在りかを指し示しているポインターのようなものなのかを意識してください。

`a = [1]` としたとき、この `a` は「リスト」であり、リストの要素の在りかを保持しているオブジェクトです。このため `a` が `a_arg`
にコピーされようが `a[0]` と `a_arg[0]` は同じ場所を指し示すので、`a_arg[0]` を更新すると `a[0]` も更新されます。

一方 `b = 1` としたとき、この `b` は `1` というデータそのものなので、これがコピーされた `b_arg` は `b` とは別に `1`
というデータを保持します。このため `b_arg` を更新しても `b` は更新されません。

したがって、質問者さんがなさいたいように `b` を `b_arg` への書き込みによって更新したいのであれば、`b` を単なる `int`
型の変数とするのではなくて、クラスで囲むという方法はあります。ありますが、今回のようなシンプルな例では `return`
を使って結果を返す方が分かりやすいだろうと思います。

これは Dart が関数の呼び出しについて値渡し (pass-by-value) を採用しているため起こる挙動です。より詳しくは、同じような現象が起こる
Java での説明が参考になるかと思います。例: <https://stackoverflow.com/q/40480/5989200>


CC BY-SA 4.0
2021-12-13T11:58:43.447
84112
2021-12-13T11:58:43.447
19110
84107
answer