Android 知识跨平台开发技术分享

Dart 2.1 的细节变化笔记总结(一)

2021-07-24  本文已影响0人  zcwfeng

编码风格默认规范

UpperCamelCase 每个单词的首字母都大写,包含第一个单词。

lowerCamelCase 除了第一个字母始终是小写(即使是缩略词),每个单词的首字母都大写。

lowercase_with_underscores 只是用小写字母单词,即使是缩略词,并且单词之间使用 _ 连接。

UpperCamelCase 风格

  1. 使用 UpperCamelCase 风格命名类型。

Classes(类名)、 enums(枚举类型)、 typedefs(类型定义)、以及 type parameters(类型参数)应该把每个单词的首字母都大写(包含第一个单词),不使用分隔符。

PS:这里包括使用元数据注解的类。,如果注解类的构造函数是无参函数,则可以使用一个 lowerCamelCase 风格的常量来初始化这个注解。

  1. 使用 UpperCamelCase 风格类型作为扩展名

extension MyFancyList<T> on List<T> { ... }

lowercase_with_underscores 风格

  1. 文件夹源文件中使用 lowercase_with_underscores 方式命名。

library peg_parser.source_scanner;
import 'file_system.dart';
import 'slider_menu.dart';

  1. lowercase_with_underscores 风格命名库和源文件名。

DO name import prefixes using lowercase_with_underscores.

import 'dart:math' as math;
import 'package:angular_components/angular_components' as angular_components;
import 'package:js/js.dart' as js;

lowerCamelCase 风格

  1. 类成员、顶级定义、变量、参数以及命名参数等 除了第一个单词,每个单词首字母都应大写,并且不使用分隔符

var count = 3;
HttpRequest httpRequest;
void align(bool clearItems) {
// ...
}

  1. 推荐 使用 lowerCamelCase 来命名常量。

const pi = 3.14;
const defaultTimeout = 1000;
final urlScheme = RegExp('^([a-z]+):');
class Dice {
static final numberGenerator = Random();
}

把超过两个字母的首字母大写缩略词和缩写词当做一般单词来对待

class HttpConnection {}
class DBIOPort {}
class TVVcr {}
class MrRogers {}
var httpRequest = ...

var uiHandler = ...
Id id;

使用 _, __, etc. 作为无用回调参数

futureOfVoid.then((_) {
print('Operation complete.');
});

顺序

要 把 “dart:” 导入语句放到其他导入语句之前。
要 把 “package:” 导入语句放到项目相关导入语句之前。

import 'dart:async';
import 'dart:html';

import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';

import 'util.dart';

要 把导出(export)语句作为一个单独的部分放到所有导入语句之后。

import 'src/error.dart';
import 'src/foo_bar.dart';

export 'src/error.dart';

避免 单行超过 80 个字符。

对所有流控制结构使用花括号。

变量

  1. 所有变量引用的都是 对象,每个对象都是一个 的实例。数字、函数以及 null 都是对象。除去 null 以外(如果你开启了 空安全), 所有的类都继承于 [Object][] 类。
  2. 在声明变量时指定类型是可选的,因为 Dart 可以进行类型推断
  3. 开启了 空安全,变量在未声明为可空类型时不能为 null。你可以通过在类型后加上问号 (?) 将类型声明为可空。例如,int? 类型的变量可以是整形数字或 null。如果你 明确知道 一个表达式不会为空,但 Dart 不这么认为时,你可以在表达式后添加 ! 来断言表达式不为空(为空时将抛出异常)。例如:int x = nullableButNotNullInt!
  4. 显式地声明允许任意类型,使用 Object?(如果你 开启了空安全)、 Object 或者 特殊类型 dynamic 将检查延迟到运行时进行。
  5. Dart 支持泛型,比如 List<int>(表示一组由 int 对象组成的列表)或 List<Object>(表示一组由任何类型对象组成的列表)。
  6. Dart 支持顶级函数(例如 main 方法),同时还支持定义属于类或对象的函数(即 静态 和 实例方法)。你还可以在函数中定义函数(嵌套 或 局部函数)。
  7. Dart 支持顶级函数(例如 main 方法),同时还支持定义属于类或对象的函数(即 静态 和 实例方法)。你还可以在函数中定义函数(嵌套 或 局部函数)。
  8. Dart 支持顶级 变量,以及定义属于类或对象的变量(静态和实例变量)。实例变量有时称之为域或属性。
  9. Dart 没有类似于 Java 那样的 public、protected 和 private 成员访问限定符。如果一个标识符以下划线 (_) 开头则表示该标识符在库内是私有的。
var name = 'Bob';
Object name = 'Bob';
String name = 'Bob';

10.默认值

在 Dart 中,未初始化的变量拥有一个默认的初始化值:null。(如果你未迁移至 空安全,所有变量都为可空类型。)即便数字也是如此,因为在 Dart 中一切皆为对象,数字也不例外。

int? lineCount;
assert(lineCount == null);

assert() 的调用将会在生产环境的代码中被忽略掉。在开发过程中,assert(condition) 将会在 条件判断 为 false 时抛出一个异常。

  1. Late variables 和 Kotlin 很像,延迟初始化
late String description;

void main() {
  description = 'Feijoada!';
  print(description);
}
  1. Final 和Const

如果你不想更改一个变量,可以使用关键字 final 或者 const 修饰变量,这两个关键字可以替代 var 关键字或者加在一个具体的类型前。一个 final 变量只可以被赋值一次;一个 const 变量是一个编译时常量(const 变量同时也是 final 的)。顶层的 final 变量或者类的 final 变量在其第一次使用的时候被初始化。

const arr=[];
var arr2 = const[];
final foo = const[];

这三种区别,只能 arr2=[1];

  1. 内置类型

Dart2.1 int to double 小变化

看注释不解释

import 'dart:math' as math;

class Circle {
  double radius;

  Circle(this.radius);

  double get area => math.pi * math.pow(radius, 2);
}

void main() {
  // Before Dart 2.1, you had to provide a trailing `.0` – `42.0` – when
  // assigning to fields or parameters of type `double`.
  // A value like `42` was not allowed.

  print(Circle(2.0).area); // Before Dart 2.1, the trailing `.0` is required.

  // With Dart 2.1, you can provide whole-number values when assigning to
  // a double without the trailing `.0`.
  print(Circle(2).area); // Legal with Dart 2.1
}

mixin, with, on 的使用

mixin AnswerMixin {
  int get answer => 42;

  @override
  String toString() => '[ $runtimeType ]';
}

class Answer with AnswerMixin {}

void main() {
  print('''
*
* Simple usage of `mixin`
*
''');
  printAnswer(Answer(), 'Use `with` to include a mixin');

  print('''
*
* More advanced usage of `mixin`
*
''');
  printAnswer(
      LogAnswer(),
      'Include many mixins by separating with commas. '
      '`$LoggingAnswerMixin` prints every time `answer` is accessed.');

  print('''
*
* The order in which mixins are included matters.
*
''');

  printAnswer(LogVerifyAnswer(), 'In this case, log then verify.');
  printAnswer(VerifyLogAnswer(), 'In this case, verify then log.');

  print('''
*
* You can extend classes that include mixins, too.
*
''');

  printAnswer(DeltaLogVerifyAnswer(), 'Verify will fail.');
  printAnswer(DeltaLogVerifyAnswer(1), 'Verify will succeed.');
}

void printAnswer(AnswerMixin obj, String description) {
  print(obj);
  print('- $description');
  print('answer: ${obj.answer}');
  print('');
}

/// [LoggingAnswerMixin] can only be used as a mixin when the superclass
/// (or one of the mixins that comes before it in a "with" clause) implements
/// [AnswerMixin].
mixin LoggingAnswerMixin on AnswerMixin {
  @override
  int get answer {
    var value = super.answer;
    print('  LOG: `answer` property was accessed');
    return value;
  }
}

class LogAnswer with AnswerMixin, LoggingAnswerMixin {}

mixin VerifyingAnswerMixin on AnswerMixin {
  @override
  int get answer {
    var value = super.answer;
    if (value == 42) {
      print('  VERIFY: Invalid Result!');
    } else {
      print('  VERIFY: valid result');
    }
    return value;
  }
}

class LogVerifyAnswer
    with AnswerMixin, LoggingAnswerMixin, VerifyingAnswerMixin {}

class VerifyLogAnswer
    with AnswerMixin, VerifyingAnswerMixin, LoggingAnswerMixin {}

abstract class DeltaAnswer with AnswerMixin {
  final int delta;

  DeltaAnswer(this.delta);

  @override
  int get answer => super.answer + delta;
}

class DeltaLogVerifyAnswer extends DeltaAnswer
    with LoggingAnswerMixin, VerifyingAnswerMixin {
  DeltaLogVerifyAnswer([int delta = 0]) : super(delta);
}

结果,可以讨论下这里,确实有点不好理清逻辑

* * Simple usage of `mixin` *
[ Answer ]
- Use `with` to include a mixin
answer: 42
* * More advanced usage of `mixin` *
[ LogAnswer ]
- Include many mixins by separating with commas. `LoggingAnswerMixin` prints every time `answer` is accessed.
LOG: `answer` property was accessed
answer: 42
* * The order in which mixins are included matters. *
[ LogVerifyAnswer ]
- In this case, log then verify.
LOG: `answer` property was accessed
VERIFY: Invalid Result!
answer: 42
[ VerifyLogAnswer ]
- In this case, verify then log.
VERIFY: Invalid Result!
LOG: `answer` property was accessed
answer: 42
* * You can extend classes that include mixins, too. *
[ DeltaLogVerifyAnswer ]
- Verify will fail.
LOG: `answer` property was accessed
VERIFY: Invalid Result!
answer: 42
[ DeltaLogVerifyAnswer ]
- Verify will succeed.
LOG: `answer` property was accessed
VERIFY: valid result
answer: 43

所有语言课本上的开胃菜

void main() {
  var i = 20;
  print('fibonacci($i) = ${fibonacci(i)}');
}

/// Computes the nth Fibonacci number.
int fibonacci(int n) {
  return n < 2 ? n : (fibonacci(n - 1) + fibonacci(n - 2));
}

result

fibonacci(20) = 6765

上一篇下一篇

猜你喜欢

热点阅读