Search code examples
dartcoding-style

is it okay to change the value of parameter inside of method in Dart?


In Dart, it is allowed that change the value of parameter in method like this

void changeValue(int num) {
  num = 10;
}

I know that above code isn't occur Error, but num = 10; can't change actual value of argument. (Because Dart is 'pass by value')

my questions are these..

  1. Is it okay to change the value of parameter?
  2. Is there any other reason or intention for Dart allowing developer can change value of parameter?

Solution

  • It's OK to change the local variable introduced by a function parameter, if you can and want to.

    You can make it impossible by making the variable final:

    void foo(final int value) {
      print(value); 
      value = value + 1; // COMPILATION ERROR: Value is `final`.
    }
    

    Most parameter variables could be final, but nobody bothers to write the final, because a mutable variable that nobody assigns to is just as good. Especially if nobody thinks about assigning to them.

    Cases where I would assign to the variable include:

    • Computed default values
      int foo([int? value]) {
        value ??= computeDefault(); // (Cannot be a constant)
        // ...
      }
      
    • Pre-processing, in case the parameter isn't always the actual value you wanted. (Could be argued that initialization is a special case of this.)
      T linkValue<T>(Link<T> node) {
        while (!node.hasValue) {
          node = node.next ?? (throw StateError("No values"));
        }
        // Do something more.
        return node.value;
      }
      
    • Unwound recursion. If you convert your tail-recursive function to a loop, it's a waste of space to introduce a new variable.
      int treeSum(BinNode? node) {
        var result = 0;
        while (node != null) {
          result += treeSum(node.left); 
          result += node.value;
          node = node.right;
        }
        return result;
      }
      
      (Or maybe this is just laziness. Guilty.)

    Your parameter variables are not final unless you want them to. Reusing them is perfectly fine, as long as you don't change the meaning of the variable. It's usually fine if the original value can reach all uses of the variable at least once. If not, then it may not be the same conceptual variable any more.