dart null 安全和打字问题

发布于 2025-01-14 17:34:25 字数 1756 浏览 2 评论 0原文

我正在尝试学习 Dart,但我很难理解空安全性。我有下面的函数,它是我直接从开发示例中复制的(https://pub.dev/packages/udp )并稍微调整了我的代码。

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();
}

但我收到以下错误:

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);
                                                                                     ^^^^

但是,如果我执行 String s = new String.fromCharCodes(datagram?.data);,我收到以下错误:

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正确吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清音悠歌 2025-01-21 17:34:25

如果左侧为 null条件成员访问运算符 (?.) 的计算结果为 null。其要点是避免通过尝试访问 null 上不存在的成员来生成空指针异常。

使用 String.fromCharCodes(datagram?.data) 不会神奇地避免调用 String.fromCharCodes 构造函数,并且 String.fromCharCodes 期望一个非空参数。

您必须为 String.fromCharCodes 提供一个保证不为 null 的值,或者必须避免调用它。示例:

// If datagram?.data is null, fall back to using an empty string.
var s = String.fromCharCodes(datagram?.data ?? '');

或者:

var data = datagram?.data;
if (data != null) {
  var s = String.fromCharCodes(data);
  ...
}

如果您还没有阅读过了解 null safety,我强烈建议您阅读已经这样做了。

请注意,?.??空感知运算符,但并不是真正的空安全。空安全是指使用类型系统来确保变量在您不希望的情况下不会为空。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文