Skip to content

When string concatenation isn’t

PHP will quite happily deal with the following:

<?php
$x = 2;
echo $x . ' is a number';

No problem. The output is 2 is a number. Try the same thing in Dart:

main() {
  num x = 2;
  print(x + ' is a number');
}

If you’re not in checked mode, this will run (and output 2 is a number), but also generate the warning ‘String is not assignable to num’. In checked mode, it will fail (‘Failed type check: type String is not assignable to type Number’).

Behind the scenes, though one might assume that print() would take a string parameter it actually takes an Object, so Dart does not implicitly call .toString() on 2. In fact, this is implemented using the left-hand-side’s operator+. Thus, the allowed right-hand-side types depend on what the left-hand-side is.

String.operator+ takes any Object, and calls .toString() on it, so the following would work as expected:

main() {
  num x = 2;
  print('The number is ' + x);
}

On the other hand, num.operator+ only accepts another num as an argument.

It’s possible to explicitly call .toString() on the left hand side first:

main() {
  num x = 2;
  print(x.toString() + ' is a number');
}

But probably the simpler method is to use string interpolation rather than concatenation:

main() {
  num x = 2;
  print('$x is a number');
}
Advertisements

Default Parameters

Parameters with default values are handy things. As a PHP developer, I can specify that certain parameters have default values, which means I don’t need to specify them every time I call a function or method. This facility is available in Dart, too.

The syntax is slightly different, however, as Dart requires optional parameters to be placed within square brackets.

So, for this PHP example:

<?php
function chased($what,
                $size = 'small',
                $chaser = 'dog',
                $where = 'up a tree') {
  print("A $size $chaser chased a $what $where");
}

chased('cat');

The equivalent in Dart would be:

chased(what, [size = 'small',
              chaser = 'dog',
              where = 'up a tree']) {
  print("A $size $chaser chased a $what $where");
}

main() {
  chased('cat');
}

Note the aforementioned square brackets around the final three optional parameters. Of course, this means all your optional parameters have to appear after the mandatory ones (i.e. those with no default value), but that’s what you’d have to do anyway; little point having an optional parameter with a mandatory one after it, since the optional one would still have to be provided.

A notable facility in Dart, however, is the ability to specify which parameters are being provided. In the PHP function above, if I only wanted to provide the $where parameter, I’d also have to provide values for $size and $chaser, even if I just wanted the defaults. That would mean going and checking what the defaults are, then using:

chased('cat', 'small', 'dog', 'down a hole');

In Dart, I can just do this:

main() {
  chased('cat', where: 'down a hole');
}

Hurrah!