美文网首页Hybrid开发
Flutter2 的 Sound null safety 是个什

Flutter2 的 Sound null safety 是个什

作者: 曹建峰 | 来源:发表于2021-03-14 15:13 被阅读0次

    Flutter2 来了

    2021年3月最大的猿圈事件莫过于Flutter Engage上,Flutter2的官宣了。
    我从燃爆的Flutter2登场视频上感受到了一个由Flutter引领的大前端新纪元的开始。

    目前的官网上有三个关于flutter2的链接.

    1. Flutter 2 is here!
    2. Announcing Flutter 2
    3. Announcing stable web

    现在你只需要写一份代码就可以支持几乎所有平台:android, iOS, macos, linux, windows,web 甚至是嵌入式平台。

    image.png

    从此我们可以集中人力、物力、精力把业务做好,跨平台的事就交给Flutter吧。

    Flutter2中有一个很重要新特性是可以帮你把app做好的。

    那就是:全面空安全(Sound null safety)以下简称空安全

    什么是全面空安全(Sound null safety)

    我们不妨将其理解为,你的变量不能包含null,除非你明确声明他们可以为空。

    有了这个空安全dart编译器能在编译阶段判断出空指针错误。

    引入空安全目的不是消灭null,而是为开发者提供工具来掌握控制null的能力。

    空安全有什么用

    空安全的作用有三个层次:

    1. 编辑提示:可以在IDE中看到语法标红的线,编译器提醒发现语法错误
    2. 提前发现:使得原本在运行时才能发现的错误,在编译时就能被发现了。
    3. 性能提升:获得大小和速度方面的改进

    空安全长什么样

    非空安全 空安全
    image image

    整个dart世界的顶层类不再是Object而是Object?
    底层类不再是Null而是Never

    基础

    默认情况下,所有变量都是非空的

    空安全里面有“?”

    nullable-hierarchy_235x119.png

    变量类型声明后面的问号:

    //如果想声明一个变量既可以是个int,也可以为空,只需要给这个变量的类型声明加个问号
    int? aNullableInt = null;
    

    函数返回值类型后面的问号:

    //返回值类型加问号代表可以返int,也可返回空
    int? getIndex() {
      return 1;
    }
    
    

    空安全里面有 ??

    ??操作符放在可空变量后面,操作符后面跟一个操作数。

    表示当变量为空时变量值为该操作数。

    //当aNullableInt为空时 value = 0
    int value = aNullableInt ?? 0;
    

    空安全里面有“!”

    在某个场景中,如果开发者能够确保一个可空变量是非空变量可以给这个变量加!

    例如

    int? getIndex() {
      return 1;
    }
    
    void main() {
      int? aNullableInt = null;
    
      List numbers = [1, 2, 3];
    
      aNullableInt = getIndex();
    
      //可以确保此处的aNullableInt是非空的
      print('numbers[${aNullableInt}]:${numbers[aNullableInt!]}');
    }
    
    

    空安全里面有“required”

    required只能加在函数命名参数类型声明之前。

    用来告诉编译器:“我后面会初始化这个变量”。

    class MyHomePage extends StatelessWidget {
      // 当编译器误认为函数的参数是可空的,你可以通过required关键字来纠正它
      MyHomePage({Key? key, required this.title}) : super(key: key);
      //...
    }
    

    空安全里面有“late”

    late关键字加在变量类型声明前。

    用来告诉编译器:“我后面会初始化这个变量”。

    class IntProvider {
      //你能确保一个变量在使用之前会被初始化为非空,但仍然被报错,你可以在变量的类型之前标记late
      late int aRealInt;
    
      IntProvider() {
        aRealInt = calculate();
      }
    }
    

    List和Map变样了

    List<String?>?

    类型 列表可以空 item可以空 描述
    List<String> No No 包含非空字符串的非空列表
    List<String>? Yes No 包含可空字符串的非空列表
    List<String?> No Yes 包含非空字符串的可空列表
    List<String?>? Yes Yes 包含可空字符串的可空列表

    Map<String, int?>?

    类型 Map可以空 item可以空
    Map<String, int> No No*
    Map<String, int>? Yes No*
    Map<String, int?> No Yes
    Map<String, int?>? Yes Yes

    实战:如何迁移你的应用到空安全

    迁移套路:

    1. 模块顺序

    先迁移被依赖的模块,再迁移依赖它的模块

    image

    我在迁移Flutterame的时候就是按照这个顺序迁移的:

    1. modules/utils
    2. modules/gallery
    3. 整个app

    2. 三板斧

    对于每个模块,我们都可以下面用这三板斧搞定:

    1. 更新pub

    dart pub get
    

    2. 查看并修改依赖类库

    查看依赖类库

    ➜ dart pub outdated --mode=null-safety
    Showing dependencies that are currently not opted in to null-safety.
    [✗] indicates versions without null safety support.
    [✓] indicates versions opting in to null safety.
    
    Package Name     Current  Upgradable  Resolvable  Latest
    
    direct dependencies:
    cupertino_icons  ✗1.0.0   ✓1.0.2      ✓1.0.2      ✓1.0.2
    
    1 upgradable dependency is locked (in pubspec.lock) to an older version.
    To update it, use `dart pub upgrade`.
    

    修改依赖类库版本

    打开模块下的pubspec.yaml文件修改dependencies下的类库版本

    name: flutterame
    #...
    dependencies:
      flutter:
      # ...
      # 修改前 cupertino_icons: ^1.0.0
      cupertino_icons: ^1.0.2
    #...
    
    

    再次更新pub

    dart pub get
    

    3. 自动或手动迁移

    自动迁移

    dart migrate --apply-changes
    

    在提交代码的时候可以查看有哪些改动,这些改动是否合理。

    手动迁移

    dart migrate
    

    输出如下:

    ➜ dart migrate
    Migrating /Users/admin/Documents/flutter/flutterame/modules/utils
    
    See https://dart.dev/go/null-safety-migration for a migration guide.
    
    Analyzing project...
    [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|]No analysis issues found.
    
    Generating migration suggestions...
    [----------------------------------------------------------------------------------------------------------------------------------------------------------------------------]
    
    Compiling instrumentation information...
    [----------------------------------------------------------------------------------------------------------------------------------------------------------------------------]
    
    View the migration suggestions by visiting:
    
      http://127.0.0.1:49736/Users/admin/Documents/flutter/flutterame/modules/utils?authToken=xNh-pu7B9Fo%3D
    
    Use this interactive web view to review, improve, or apply the results.
    When finished with the preview, hit ctrl-c to terminate this process.
    
    If you make edits outside of the web view (in your IDE), use the 'Rerun from
    sources' action.
    

    然后打开"127.0.0.1:49736..."那个链接你可以进入下面这个页面

    migrate.png

    可以选择相应文件,点击代码中的非空相关的判断(蓝色提示),然后你就能够在右下角看到dart编译器为什么会做出这些判断。你可以接受这个判断或者改变它。

    迁移成果:

    完成迁移之后,我对比了迁移前后的app size差别。

    3.8M的libapp.so减少了124.7k

    appsize.png

    既能减少错误,又能减小体积,你还等什么,赶快把你的项目迁移到空安全吧!

    参考:

    Sound null safety

    Migrating to null safety

    相关视频:

    Dart 的空类型安全

    Dart 语言健全的空安全机制

    将应用迁移至 null safety (Migrating a Package to null safety)


    转载请保持文章完整性并注明出处

    如果你觉得本文有用就点个 赞 吧❤️

    如果你觉得这篇文章可能帮到别人就转发一下吧

    我会持续关注Flutter新技术,更新相关文章关注我不错过精彩内容

    相关文章

      网友评论

        本文标题:Flutter2 的 Sound null safety 是个什

        本文链接:https://www.haomeiwen.com/subject/dsiqcltx.html