Dart之旅
一。重要概念
1.所有的变量都是个对象,而所有的对象都是类的实例,甚至数字,函数以及null都是对象,包括null异常在哪,所有对象都继承自Object。
2.Null safety(空安全)是从2.12版本的dart引入的
3.尽管dart是强类型的,但是类型注解也是可用的因为dart可以推断类型
4.如果启用null safety,变量不能包含null,除非你告诉他们可以为空。你可以在变量类型的后面跟上一个?来是一个变量变为可空的。
比如说,一个变量的类型是int?那么它可能是一个integer也坑是个null,如果你知道一个表达式不可能值为null,但是Dart语言不允许,你可以在他后面加一个!来生命他不会为空(如果它真的为空了,就会抛出一个异常)
5.当你想显式的声明变量,那么什么类型都可以用,比如Object?(如果启用了null safety),Object或者-如果你一定要推迟类型检查直到runtime才推断(也就是特殊的类型dynamic)
6.Dart支持范型,比如List<int>或者List<Object>
7.Dart支持顶级函数(比如main()),也支持类上或者是对象上的函数(也就是静态函数和成员函数),你同样也可以在函数内创建函数(也就是嵌套函数或者是本地函数)
8.相似的,Dart支持顶级变量同样支持静态变量和成员变量。成员变量有时候也被称为字段or属性。
9.不像Java,Dart没有public,protected,和private 关键字,如果一个变量or函数or类是开头的,那么他就是private。
10.标识符(类,函数,方法等)可以用小写字母开头或者下划线开头(),然后任意组合小写字母,下划线数字等
11.Dart有表达式(有运行时的值)和声明(没有运行是的值),比如,条件表达式?:expr1:expr2有一个值要么是expr1,要么是expr2。与之相比的就是if-else语句,它并没有值。一个语句通常包括一个或者多个表达式,但是一个表达式却不能直接包含一个语句。
12.Dart工具能报告两种类型的问题:warning和error,Warning只是提示代码可能会出错但是并不阻止程序的执行,Error既可以在编译时也可以在运行时出现,编译时的error阻止带啊吗的继续执行,而 一个代码运行时的error则会导致一个异常的抛出。
关键字:
1.abstract:抽象类or抽象方法
2.else
3.import:导包
4.show/hide:Importing only part of a library
// Import only foo.
import 'package:lib1/lib1.dart' show foo;
5.as:类型转换,类似于Android studio 中的cast
(employee as Person).firstName = 'Bob';
6.enum:枚举
enum Color { red, green, blue }
使用:Color.blue
7.in:主要用于循环
for (final candidate in candidates) {
candidate.interview();
}
8.static:静态类,方法,对象,字段
9.assert:断言
在开发中用一个断言语句-assert(condition,optionalMessage);来中断一个常规的执行如果一个 条件语句的结果是false。比如:
// Make sure the variable has a non-null value.
assert(text != null);
// Make sure the value is less than 100.
assert(number < 100);
// Make sure this is an https URL.
assert(urlString.startsWith('https'));
10.export:类似于build.gradle里面的exclude
11.interface:接口
12.super:父类
13.async:异步
Dart库里面充满了返回Future或者Stream对象的函数,这些函数就是异步的。这些函数经过一段时间的耗时操作,不用等到这些操作完成(没懂!!!)
async/await是支持异步编程的关键字,让你把异步代码写的像同步代码一样。
Future<void> checkVersion() async {
var version = await lookUpVersion();
// Do something with version
}
14.extends:继承
15.is:判断类型使用,类似于Java中的instanceOf
if (employee is Person) {
// Type check
employee.firstName = 'Bob';
}
16.switch:分支,和Java中一样
17.await:异步编程。和async配合使用
await lookUpVersion();//使异步代码同步执行
想要使用await,代码必须在一个async方法中也就是方法要被async标记
Future<void> checkVersion() async {
var version = await lookUpVersion();
// Do something with version
}
18.extension:扩展(如扩展函数)类似于Kotlin
扩展方法是向已有库中增加实用性的一种方式,你可能在不经意间就在用扩展方法,比如说,当你在IDE里面做代码补全的时候,他就会在常规方法旁边建议一些扩展方法。
19.late:2.12版本增加的关键字
1.生命一个非空变量,可以先声明后初始化
2.懒初始化一个变量
Dart的流分析一般都会在非空变量使用前检测到被赋值了一个非空的值但有的时候还是会分析失败。
如果你确定一个变量在使用前已经被赋值,但是,dart 不允许,你可以把这个变量设置为late来修复这个问题:
late String description;
void main() {
description = 'Feijoada!';
print(description);
}
20.sync:
21.break:跳出循环或者跳出分支,和Java一样
22.external:
23.library:就是库文件
24.this:构造函数中使用
class Point {
double x = 0;
double y = 0;
// Syntactic sugar for setting x and y
// before the constructor body runs.
Point(this.x, this.y);
}
25.case:和switch配合使用
26.factory:Factory constructors
实现一个构造器但是并不是每次都创建这个类的实例时,就可以使用factory关键字。比如说,factory constructor可能会在缓存里面返回一个实例,也可能返回一个子类型的实例。在初始化列表中使用逻辑不能初始化一个final变量时也可以使用factory constructor。
下面的例子中Logger factory constructor从缓存中返回了对象,Logger.fromJson factory constructor从一个Json Object中初始化了一个final变量。
class Logger {
final String name;
bool mute = false;
// _cache is library-private, thanks to
// the _ in front of its name.
static final Map<String, Logger> _cache =
<String, Logger>{};
factory Logger(String name) {
return _cache.putIfAbsent(
name, () => Logger._internal(name));
}
factory Logger.fromJson(Map<String, Object> json) {
return Logger(json['name'].toString());
}
Logger._internal(this.name);
void log(String msg) {
if (!mute) print(msg);
}
}
27.mixin:Adding features to a class
Mixins是在多个类继承关系里面重用代码的一种方式。
为了使用mixin使用with关键字后面跟着一个或者多个mixin的名字。下面的例子就展示了使用mixins的两个类。
class Musician extends Performer with Musical {
// ···
}
class Maestro extends Person
with Musical, Aggressive, Demented {
Maestro(String maestroName) {
name = maestroName;
canConduct = true;
}
}
想要实现一个mixin,需要创建一个类继承自Object然后声明一个无参构造。请使用mixin关键字而不是class关键字,除非你要把这个mixin也可以当作一个常规的类来使用。
mixin Musical {
bool canPlayPiano = false;
bool canCompose = false;
bool canConduct = false;
void entertainMe() {
if (canPlayPiano) {
print('Playing piano');
} else if (canConduct) {
print('Waving hands');
} else {
print('Humming to self');
}
}
}
有时候你可能想要限制可以使用mixin的类型,比如说,mixin可能依赖于一个可以调用某个方法的类,但是这个方法并没有在mixin中定义。像下面的例子,你可以限制mixin的使用通过on这个关键字来指定需要的父类
class Musician {
// ...
}
mixin MusicalPerformer on Musician {
// ...
}
class SingerDancer extends Musician with MusicalPerformer {
// ...
}
在以上代码中,只有继承或者实现了Musician的类才可以使用MusicalPerformer这个mixin,因为SingerDancer继承自Musician,SingerDancer可以使用MusicalPerformer这个mixin。
28.throw:抛出异常
29.catch:捕获异常
try {
breedMoreLlamas();
} on OutOfLlamasException {
buyMoreLlamas();
}
try {
breedMoreLlamas();
} on OutOfLlamasException {
// A specific exception
buyMoreLlamas();
} on Exception catch (e) {
// Anything else that is an exception
print('Unknown exception: $e');
} catch (e) {
// No specified type, handles all
print('Something really unknown: $e');
}
30.false:就是false
31.new:和Java一样,使用构造创建实例的时候,new可以省略
32.true:就是true
33.class:就是class
34.final:就是final
35.null:
未初始化的可空的类型的变量有个初始化的值是null,如果你没有指定空安全,那么每一个变量都有一个可空的类型,甚至数字类型的变量的初始化的值也是null,因为数字和Dart里的其他类型一样,都是对象。
int? lineCount;
assert(lineCount == null);
36.try:就是try
37.const:常量
38.finally:同Java
39.on:与try-catch配合使用,用来捕获指定异常
40.typedef:type的别名,通常被称为typedef是因为它是被关键字typedef声明的,是一种推断类型的简洁的方式。
typedef IntList = List<int>;
IntList il = [1, 2, 3];
typedef ListMapper<X> = Map<X, List<X>>;
Map<String, List<String>> m1 = {}; // Verbose.
ListMapper<String> m2 = {}; // Same thing but shorter and clearer.
2.13之前,typedef只能在function上使用,要使用typedef新的特性,需要将dart升级到2.13以上
41.continue:同Java
42.for:
var message = StringBuffer('Dart is fun');
for (var i = 0; i < 5; i++) {
message.write('!');
}
var callbacks = [];
for (var i = 0; i < 2; i++) {
callbacks.add(() => print(i));
}
callbacks.forEach((c) => c());
for (final candidate in candidates) {
candidate.interview();
}
var collection = [1, 2, 3];
collection.forEach(print); // 1 2 3
```
43.operator:操作符
44.var:生命变量
45.default:与switch配合使用
46.get/set:
class Rectangle {
double left, top, width, height;
Rectangle(this.left, this.top, this.width, this.height);
// Define two calculated properties: right and bottom.
double get right => left + width;
set right(double value) => left = value - width;
double get bottom => top + height;
set bottom(double value) => top = value - height;
}
void main() {
var rect = Rectangle(3, 4, 20, 15);
assert(rect.left == 3);
rect.right = 12;
assert(rect.left == -8);
}
>47.required:用在方法中表示参数必填
48.do/while:同Java
49.deferred:懒加载,在用到的时候在加载某些库
import 'package:greetings/hello.dart' deferred as hello;
50.with:和mixin配合使用
51.yield:和sync配合使用
52.dynamic:未指定类型,直到运行时
网友评论