Dart 空安全 技术预览版2

Why null safety?

空安全是一个非常具有生产力的功能,能够帮助你避免空异常。除此之外它也能有一定程度上的性能提升。

Dart是一个类型安全的语言。这意味着当你定义了某类型的变量时,编译器可以保证该变量是确定的类型。当时却无法保证该类型是非空的。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

// This app simulates possible null errors. Try running it and see if it fails.
// You can then try to hot reload a few times; you should see it occasionally
// failing and occasionally succeeding.
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Get data from services. Note: in a real application,
    // these would be async calls, but we’re using sync calls
    // for simplicity.
    final localizedAppName = Config.getAppName();
    final temperatures = WeatherService.getTemperatures();

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text(localizedAppName)),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('Temperature next 3 days:'),
              for (final t in temperatures) Text(t.round().toString()),
            ],
          ),
        ),
      ),
    );
  }
}

class Config {
  static String getAppName() {
    // Imagine this looks up a localized version of the app name. We're using
    // the current time to simulate a variance in responses.
    if (DateTime.now().second.isEven) {
      return 'Weather forecast';
    } else {
      // Oops, we don't have a localization.
      return null;
    }
  }
}

class WeatherService {
  static List getTemperatures() {
    // Imagine this makes a network call to get the current temperature.
    // We're using the current time to simulate a variance in responses.
    if (DateTime.now().millisecond.isEven) {
      return [32.2, 34.5, 31.0];
    } else {
      if ((DateTime.now().second / 10).round().isEven) {
        // Oops, we couldn't get any temperatures.
        return null;
      } else {
        // Oops, we couldn't get one of the temperatures.
        return [32.2, 34.5, null, 31.0];
      }
    }
  }
}

以上代码将会在 for loop 和Text文本出现空异常。

Screenshot of the preceding code with null errors

而对于空安全检查,编译器将会分析代码,对于为空的位置以红色波浪形做出提示。

Null safety principles

1.Non-nullable by default.除非显示指定某个变量可为空,否则都会被编译器视为非空。

// In null-safe Dart, none of these can ever be null.
var widget = Text('Hello');
final status = GetStatus();
String m = '';

对于以上代码,如果在项目中之后的代码将widget设置为null,开发者将会得到静态分析错误和红色波浪线提示,编译器也会拒绝编译。

1.1 Nullable variables
如果你想要设置某个变量可以为空,可以使用?,比如

// These are all nullable variables.
Text? t = Text('Hello');  // Can be null later.
final Status? s = getStatus();  // Maybe the function returns null.
String? n;  // Is null at first. Can be null at any later time, too.

​ 也可以设置函数参数和返回值为空

// In function parameters.
void initialize(int? count) {
  // It's possible that count is null.
}
// In function return values.
static List? getTemperatures() {
  // Can return null instead of a List, and the list can contain nulls.
}

1.2 Being productive with null safety
空安全并不仅仅是关于安全,也是简单易用,具备生产力的。

void honk(int? loudness) {
  if (loudness == null) {
    // No loudness specified, notify the developer
    // with maximum loudness.
    _playSound('error.wav', volume: 11);
    return;
  }
  // Loudness is non-null, let's just clamp it to acceptable levels.
  _playSound('honk.wav', volume: loudness.clamp(0, 11));
}

2.Incrementally adoptable.开发者可以自主选择迁移时间,并且一部分一部分迁移。在同一个工程内可以同时有空安全代码和非空安全代码。同时为开发者提供了帮助迁移的工具。基于稳定性考虑,在进行项目迁移的时候官方建议根据依赖顺序进行。

3.Fully sound. Dart空安全是非常健全的。这意味着我们完全可以信任类型系统:如果它判定某个对象非空,那就肯定不会为null。只要把工程和依赖迁移到空安全,不仅会减少代码,也会生成更小的二进制文件和更快的执行效率。

The null safety roadmap

1.Flutter experimentation with *technical preview 2*:当前阶段;

2.Early package migration with *beta*: 今年晚些时候;

3.Production use with stable:大概在明年;

参考自Dart sound null safety: technical preview 2

你可能感兴趣的:(Dart 空安全 技术预览版2)