今天对于DART团队来说是一个重要的里程碑,因为我们的零安全工作的技术预览。空安全性可以帮助您避免一类通常很难发现的错误,并且作为一个额外的好处,它可以实现一系列性能改进。我们现在发布早期的技术预览,我们期待您的反馈。
这篇文章描述了DART团队推出零安全的计划。它还解释了我们所说的声音空安全性是什么意思,以及为什么它不同于许多其他语言采用的方法。
DART是一种类型安全语言。这意味着当您获得某种类型的变量时,编译器可以保证它属于该类型。但是类型安全本身并不能保证变量不为空。
空错误非常常见。在GitHub上搜索会发现数千个由DART代码中的空值引起的问题,甚至还有数千个提交试图修复这些问题。
尝试查看是否可以在下面的示例代码中发现可空性问题:
如果使用NULL调用此函数,肯定会失败,但还有第二种情况需要考虑:
void main(){//错误情况1:将NULL传递给文件。printLengths(Null);//错误情况2:传递文件列表,包含null项。printLengths([File(';filename1';),File(';filename2';),null]);}。
使用空安全性,您可以更有信心地对代码进行推理。不再出现令人讨厌的运行时空取消引用错误。相反,您在编码时会收到静态错误。
DART的零安全是可靠的。这意味着在上面的示例中,DART百分之百确定文件列表和其中的元素不能为空。当DART分析您的代码并确定某个变量不可为空时,该变量始终不可为空:如果您在调试器中检查正在运行的代码,您将看到在运行时保持不可为空。相比之下,其他一些实现并不可靠,在许多情况下仍然需要执行运行时空检查。DART与SWIFT共享听起来像零的安全性,但其他编程语言不是很多。
DART的空安全性的健壮性还有另一个值得欢迎的含义:它意味着您的程序可以更小、更快。由于DART确实确定文件不会为空,因此DART可以进行优化。例如,DART Ahead-of-time(AOT)编译器可以生成更小、更快的本机代码,因为当它知道某个变量不为NULL时,它不需要添加对NULL的检查。
我们已经看到了一些非常有希望的初步结果。例如,我们看到模拟典型颤动框架渲染模式的微基准测试的性能提高了19%。
在开始零安全详细设计之前,DART团队定义了以下三个核心原则:
默认情况下不可为空。除非您显式地告诉DART变量可以为空,否则它将认为该变量不可为空。我们选择此选项作为默认值,因为我们发现到目前为止,非NULL是API中最常见的选择。
逐渐可采用的。外面有很多DART代码。必须能够逐个部分地增量地迁移到零安全。在同一项目中应该可以有空安全代码和非空安全代码。我们还将提供工具来帮助您进行迁移。
完好无损。如上所述,DART的零安全性是可靠的。一旦您将整个项目和依赖项迁移到零安全,您就可以获得健全性的全部好处。
核心语法非常简单。下面是一些不可为空的变量,它们以不同的方式声明。请记住,不可为空是默认设置,因此这些声明看起来就像今天一样,但它们的含义发生了变化。
//在空安全DART中,这些都不能为空。var i=42;最后b=foo();字符串m=';';;
DART将确保您永远不会将NULL赋给上述任何变量。如果您尝试在一千行之后执行i=null,您将得到一个静态分析错误和红色的曲折线条,并且您的程序将拒绝编译。
//这些都是可以为空的变量。INT?j=1;//以后可以为空。最后的Foo?c=getFoo();//函数可能返回NULL。绳子?n;//开始为空。在以后的任何时间也可以为空。
//在函数参数中。void bogie(int?count){//计数可能为空。}//在函数返回值中。福?getFoo(){//可以返回null而不是foo。}//还有:泛型、typedefs、类型检查等。//以及以上内容的任意组合。
但是,再一次,我的梦想是你几乎永远不需要使用?您的绝大多数类型将是不可为空的。
DART团队正在努力使零安全尽可能易于使用。例如,请看下面的代码,它使用if检查空值:
无效喇叭(int?响度){如果(响度==NULL){//没有指定响度,请通知开发商//最大响度。_playSound(';error.wav&39;,volume:11);return;}//响度不为空,让我们将其钳制到可接受的水平。_playSound(';honk.wav';,音量:Loudness.clip(0,11));}。
请注意,DART是如何足够聪明地意识到,在我们传递if语句时,响度变量不能为空。因此,DART允许我们调用CLAMP()方法,而无需跳转。这种便利性是通过所谓的流分析实现的:DART分析器会像执行代码一样检查您的代码,自动找出有关代码的附加信息。
下面是另一个示例,它显示了DART可以确保变量是非NULL的情况,因为我们始终为其赋值为非NULL值:
int sign(Int X){//结果不可为空。INT RESULT;IF(x&>;=0){RESULT=1;}ELSE{RESULT=-1;}//此时,DART知道结果不能为空。返回结果;}。
如果删除上面的任何赋值(例如,通过删除结果=-1;行),DART不能保证结果为非空:您将得到一个静态错误,并且您的代码将不会编译。
流分析只在函数内部工作。如果您有全局变量或类字段,则DART不能保证何时为其赋值。DART无法对整个应用程序的流进行建模。因此,如果在第一次读取变量之前知道变量将为非NULL,但不能立即对其进行初始化,则可以使用new late关键字。
请注意,尽管v开始时未初始化,但它是非空的。DART相信您在为v赋值非空值之前不会尝试读取v,并且您的代码编译时不会出错。
DART团队已经工作了一年多,以确保技术预览的零安全性。这是自我们引入DART 2以来对DART语言增加的最大一项功能。然而,这并不是一个突破性的变化。现有代码可以调入使用空安全性的代码,反之亦然。即使在零安全性可用之后,它也将是一个可选功能,您可以在准备好时采用。您的现有代码将继续运行,无需更改。
我们最近迁移了DART核心库,以充分使用空安全性。作为null security向后兼容性的一个示例,我们替换了现有的核心库,而不会破坏在DART和Ffltter测试环境中运行的现有测试和测试应用程序。我们甚至将新的核心库直接放入他们的产品代码库中,毫无障碍地提供给许多Google内部客户。我们计划在功能启动时迁移我们所有的软件包和应用程序,以使用空安全,我们希望您也能这样做。但是你可以在你的时间表上,一个包接一个包,一个应用一个应用。
技术预览。这将于今天发布,并在DART的开发频道中提供。有关详细信息,请参阅下面的“立即试用”部分。情况仍然会发生变化,所以暂时不要在生产代码中使用空安全性。不过,一定要测试一下,然后给我们反馈!
测试版。零安全将在DART的测试通道中提供,并且不再是在实验旗帜后面。该功能将非常接近预期的最终版本。如果您拥有pub.dev包或插件,那么现在就可以开始迁移了,但是您还不应该将其发布为稳定版本。
稳定释放。每个人都将拥有零安全性,并鼓励您将迁移后的包和插件发布为稳定版本。您还应该迁移您的生产应用程序。
如果一切顺利,我们计划在年底前将null security作为一个稳定的功能发布。从现在到那时,我们将添加工具来帮助您确保代码为空的安全,包括:
支持您自动执行升级现有软件包和应用程序的许多步骤的迁移工具。
标签,这样您就可以判断一个包是否支持空安全性。
pub过时命令的扩展,支持查找支持空安全性的依赖项的最新版本。
现在尝试零安全的最快方式是使用nullsafety.dartpad.dev,这是一个启用了零安全的Dartpad版本。打开“使用代码段学习”下拉列表,可以找到一系列学习练习,这些练习演练了空安全的新语法和基础知识。
您还可以在小型命令行应用程序中尝试空安全性。(我们还没有迁移像Ffltter这样的大型框架。)。首先下载dev-channel DART SDK的副本,然后获取此示例DART CLI应用程序的副本(GitHub repo、zip存档)。示例应用程序的自述文件包含使用空安全实验标志运行应用程序的说明。示例中的其他文件提供了启动配置,可以在VS Code和Android Studio中进行调试。
我们很高兴能为DART带来零安全。声音空安全性是DART的一个独特功能,它可以帮助您编写不太容易出错的代码并获得更好的性能。我们希望您在技术预览中试用该功能,并通过我们的问题跟踪器给我们反馈。快乐的编码!