I'm trying to learn Dart, but I'm having a really hard time wrapping my head around the Null Safety. I have the function below, which I copied straight from the dev example (https://pub.dev/packages/udp) and tweaked for my code just slightly.
void udpConnection(port) async {
var sender = await UDP.bind(Endpoint.any(port: Port(65000)));
var dataLength = await sender.send('Hello World!'.codeUnits, Endpoint.broadcast(port: Port(port)));
var receiver = await UDP.bind(Endpoint.loopback(port: Port(65002)));
try {
receiver.asStream(timeout: Duration(seconds: 20)).listen((datagram) {
String s = new String.fromCharCodes(datagram.data);
print(s);
});
} catch(e) {
print(e);
}
// close the UDP instances and their sockets.
sender.close();
receiver.close();
}
But I get the following error:
Error: Property 'data' cannot be accessed on 'Datagram?' because it is potentially null.
- 'Datagram' is from 'dart:io'.
Try accessing using ?. instead.
String s = new String.fromCharCodes(datagram.data);
^^^^
However, if I do String s = new String.fromCharCodes(datagram?.data);
, I get the following error:
Error: The argument type 'Uint8List?' can't be assigned to the parameter type 'Iterable<int>' because 'Uint8List?' is nullable and 'Iterable<int>' isn't.
- 'Uint8List' is from 'dart:typed_data'.
- 'Iterable' is from 'dart:core'.
String s = new String.fromCharCodes(datagram?.data);
^
How can I access the data property of the Datagram correctly?
The conditional member access operator (?.
) evaluates to null
if the left-hand-side is null
. The point of it is to avoid generating a null-pointer exception by attempting to access a non-existent member on null
.
Using String.fromCharCodes(datagram?.data)
would not magically avoid calling the String.fromCharCodes
constructor, and String.fromCharCodes
expects a non-null argument.
You either must give String.fromCharCodes
a value that you guarantee is not null
or must avoid calling it. Examples:
// If datagram?.data is null, fall back to using an empty string.
var s = String.fromCharCodes(datagram?.data ?? '');
or:
var data = datagram?.data;
if (data != null) {
var s = String.fromCharCodes(data);
...
}
I strongly recommend reading Understanding null safety if you haven't already done so.
Note that ?.
and ??
are null-aware operators but aren't really about null-safety. Null-safety is about using the type system to ensure that variables cannot be null
when you don't expect them to be.