Swift vs Dart
-
相同特性
- 支持null类型安全
- collections, generics, concurrency (using async/await), and extensions.
-
Dart特有
- Mixins,和Swift一样支持预先编译AOT(Ahead-Of-Time)compilation,同时也支持JIT(Just-In-Time)compilation模式,可以增量编译和debug
Lint:静态解析
拓展阅读:Customizing static analysis 、dart fix解析修复、IDE的Dart Format、Effective Dart and Linter rules.
变量Variables
final = let, var =var(支持类型推断)
const常量定义、const 数据定义
const bar = 100; // 常量 constant variables
// in class 使用 static const
class StandardAtmosphere {
static const bar = 100;
static const double atm = 1.0 * bar; //
}
final name = 'Bob'; // immutable 仅设置一次 相当于 let name = "Bob"
// final 和 const区别
final foo1 = const [1, 2, 3];
const foo2 = [1, 2, 3];
const bar2 = foo2; // oK
const bar1 = foo1; // Compile-time Error!!!
内建类型
拓展阅读: Built-in types
-
基础数据类型
- Numbers(num、int、double)
-
int intVariable = 3; double doubleVariable = 3.0; print(intVariable == doubleVariable); // true - 拓展阅读:Numbers in Dart
- String(String)
-
final singleQuotes = 'T'm learning Dart'; final unicode = '\u{1F60E}'; //😎, Unicode scalar U+1F60E var food = 'bread'; var str = 'I eat $food'; var str1 = 'I eat ${bakery.bestSeller}'; // 和 Swift一样支持""" final str2 = """ 123 456 789"""; // Raw String 和Swift.# = Dart=.r // Swift: let str3 = #"name1 \n name2"# final str3 = r""" 123 456 \n 789"""; var str4 = "name".toUpperCase; // NAME - 拓展阅读:Runes and grapheme clusters
- Booleans(bool)
-
集合数据类型
- 数组List/Array(List)
- 集合Set(Set)
- 字典Map/Dictionary(Map)
-
可选类型
a ??= b; // a = a ?? b
非空,用时初始化标识
未初始化,先用,则会出发运行时错误!
使用场景之一:lazy load懒加载
class Weather {
late int _temperature = _readThermometer();
}
函数Function
- Main
void main() {
// main function is the entry point
print('hello world');
}
不支持元组Tuples?但是:several tuple packages
Error:平常指的是程序错误或系统级别的failures失败,不必捕捉的
Exception:平常是指可以恢复的failure失败,想要被cathc捕捉到的
- Try-catch
try {
// Create audio player object
audioPlayer = AVAudioPlayer(soundUrl);
// play the sound
audioPlayer.play();
}
catch {
// couldn't create the player for file,log the exception
print('couldn't create the player for file $soundFileName,log the exception');
}
拓展阅读:exceptions and errors.
- Parameters-函数参数
// 设置默认值a,b Positional Parameter;c,d Named Parameter { 内的定义 }
int multiply(int a, int b, {int c = 1, int d = 1}) {
return a * b * c * d;
}
multiply(2, 3);
multiply(2, 3, c: 2);
int multiply(int a, { required int b }){
return a * b;
}
multiply(2, b: 3);
// 注意:可选占位参数必须在required 之后,不能和Named Parameter混用
// 可选Positional Parameter
int multiply(int a, int b, [int c = 1, int d = 1]){
return a * b * c * d;
}
multiply(1, 2);
multiply(1, 2, 3, 4);
- First-class Functions - 函数是一等公民
// 函数可以作为参数、返回值使用
typedef int MultiplyFunction(int value);
MultiplyFunction multiplyBy(int multiplier) {
return (int value) {
return value * multiplier;
}
}
MultiplyFuntion funcByTwo = multiplyBy(2);
// call
print(funcByTwo(3)); // 6
-
匿名函数 Anonymous Funtion= Swift的闭包
- 创建方式
// 方式一
// map return Interable<T> 而不是List<T>所有要使用toList()
[1, 2, 3].map((elment) {
return element * 2;
}).toList(); // [2, 4, 6]
// 单行 实现
[1, 2, 3].map ((element) => element * 2).toList();
// 普通函数也适用
multipy(int a, int b) => a * b;
int multipy(int a, int b) {
return a * b
}
同步函数生成器-Iterable
// 同步函数生成器
Iterable<int> listNumbers(int n) sync* {
int k = 0;
while (k < n) yield k++;
}
// Returns an `Iterable<int>` that iterates
// through 0, 1, 2, 3, and 4.
print(listNumbers(5));
Iterable<int> doubleNumbersTo(int n) sync* {
int k = 0;
while (k < n) {
yield* [k, k];
k++;
}
}
// Returns an iterable with [0, 0], [1, 1], and [2, 2].
print(doubleNumbersTo(3));
异步函数生成器使用-streams,拓展阅读:Concurrency
Statements声明
-
控制流
- if-else
var a = 1;
if (a == 1) {
a = 1;
} else if (a == 2) {
a = 2;
} else {
a = 3;
}
if (a == 1) a = 1;
print(a);
条件判断加了()
- For-in
// 数组遍历
var list = [0, 1, 2];
for (var i in list) {
print(i);
}
// Map 遍历没有 for- in;使用Map.forEach
Map<String, int> dict = {
'Foo': 1,
'Bar': 2
}
for (var e in dict.entries) {
print('${e.key}, ${e.value}');
}
dict.forEach((key, value)) {
print('$key, $value');
});
-
- 操作符重载
class Vector {
final double x;
final double y;
final double z;
Vector operator +(Vector v) {
return Vector(x: x + v.x, y: y + v.y, z: z + v.z);
}
}
Swift可以自定义运算符
- 算数运算符
assert(2 + 3 == 5);
assert(2 - 3 == -1);
assert(2 * 3 == 6);
assert(5 / 2 == 2.5); // Result is a double
assert(5 ~/ 2 == 2); // Result is an int
assert(5 % 2 == 1); // Remainder
a = 0;
b = ++a; // Increment a before b gets its value.
assert(a == b); // 1 == 1
a = 0;
b = a++; // Increment a AFTER b gets its value.
assert(a != b); // 1 != 0
web和native可能有所不同,~/ 是floor(截取) 和 而不是round(向上取整)
var person = Employee();
var person1 = Persion();
(person as Employee).employeeNumber = 123;
if (person1 is! Employee) print('Not Employee');
if (person1 is Person) {
print(' A Person');
person1.name = 'Bob'; // 可以使用name属性了
}
拓展阅读:see Bitwise operations in the Numbers in Dart page.
- 位运算符
final value = 0x22;
final bitmask = 0x0f;
assert((value & bitmask) == 0x02); // AND
assert((value & ~bitmask) == 0x20); // AND NOT
assert((value | bitmask) == 0x2f); // OR
assert((value ^ bitmask) == 0x2d); // XOR
assert((value << 4) == 0x220); // Shift left
assert((value >> 4) == 0x02); // Shift right
// Result may differ on the web
assert((-value >> 4) == -0x03); // Shift right
跨平台使用 可能结果不同,详见 Bitwise operations
- Cascades(.. 操作符)
Animal animal = Animal()
..name = 'Bob'
..age = 5
..feed()
..walk();
print(animal.name); // Bob
print(animal.age)l // 5
Collections集合
final List<String> list1 = <String>['one', 'two', 'three'];
final list2 = <String>['one', 'two', 'three'];
final list3 = ['one', 'two', 'three'];
final string = list1[1];
list1.add('four');
list1.addAll(['five', 'six']);
不可变数组
// 1. 编译时常量数组
const list3 = ['one', 'two', 'three'];
// 2. final 不可更改为其他的list,但可以增/删元素个数
final list4 = ['one', 'two', 'three'];
// 3. 不可更改数组元素个数
final list5 = List<String>.unmodifiable['one', 'two', 'three'];
展开操作符Spread Operators(...)
final list = [1, 2];
final list1 = [0, ...list]; // [0, 1, 3]
List<int>? list;
// Swift: let list2 = [0] + list ?? []
final list2 = [0, ...?list]; // [0]
// Swift Dictionary Key的类型 KeyType:Hashable
final gifts = {'first': 'partridge','second': 'turtle doves','fifth': 'golden rings',};
final nobleGases = {2: 'helium',10: 'neon',18: 'argon',};
final gift = gifts['first']; // ‘partridge'
assert(gifts.containsKey('fifth')); // false
gifts['third'] = 'turtle'; // Gets added
gifts['second'] = 'turtle doves'; // Gets updated
gifts.remove('first');
gifts.removeWhere((key, value) => value == 'partridge');
Dart hashCode集成子Object类,
hashCode property
// Swift: var abc: Set<String> = ["a", "b"]; // String: Hashable
final abc = {'a', 'b', 'c'};
final abc = Set<String>.unmodifiable(['a', 'b', 'c']);
Classes
不支持值类型,所以没有Struct
Enums枚举类型,Dart2.17增强了枚举类型的使用,支持继承、设置state和添加方法
拓展阅读: Declaring enhanced enums
- Constructors构造函数
// 标准构造函数,new不建议使用了
class Point {
double x = 0;
double y = 0;
Point(double x, double y) {
this.x = x;
this.y = y;
}
}
Point p = Point(2, 1.0);
// 构造函数,语法糖
class Point {
double x = 0;
double y = 0;
Point(this.x, this.y);
// With an optional positioned parameter
Point(this.x, [this.y = 0]);
// With named parameters
Point({required this.y, this.x = 0});
// With both positional and named parameters
Point(int x, int y, {int scale = 1}) {...}
// Delegates to the main constructor.
Point.alongXAxis(double x) : this(x, 0);
}
Initializer lists
class Point {
double x = 0;
double y = 0;
// 常量类型构造器
const Point(this.x, this.y);
// Named Constructor
Point(Map<String, double> json)
: x = json['x']!,
y = json['y']! {
print('Point = ($x, $y)');
}
}
工厂构造器,使用场景如:返回缓存的对象
class Logger {
static final Map<String, Logger> _cache = <String, Logger>{}
// Factory constructor that returns a cahched copy,
// or creates a new one if it's not yet availabe
factory Logger(String name) => _cache[name] ??= Logger._internal(name);
Logger._internal(this.name);
}
Getter & Setter
class Rectangle {
double left, top, width, height;
Rectangle(this.left, this.right, this.width, this.height);
// 计算属性
double get right => width + left;
set right(double value) => width = value - left;
double get bottom => top + height;
set bottom(double value) => height = value - top;
}
- 抽象类实现
拓展阅读: abstract classes, implicit interfaces, and extending a class sections
abstract class AbstractContainer {
void updateChildren();
String toString() => "AbstractContainer";
}
abstract class Animal {
int getLegs();
void makeNoise();
}
class Dog implements Animal {
@override
int getLegs() => 4;
@override
void makeNoise() => print('Woof Woof!!!');
}
// 或者
class Dog extends Animal {
// ...
}
- Mixin 混合
abstract class Animal {}
// Defining the mixins
mixin Flyer {fly() => print('Flaps wings');}
mixin Walker {walk() => print('Walks legs');}
class Bat extends Animal with Flyer {}
class Goose extends Animal with Flyer, Walker {}
class Dog extends Animal with Walker {}
// Correct calls
Bat().fly();
Goose().fly();
Goose().walk();
Dog().walk();
// Incorrect calls
Bat().walk(); // Not using the Walker mixin
Dog().fly(); // Not using the Flyer mixin
class Animal {
}
方法响应栈
// Bird > Flyer > Consumer > Animal
class Bird extends Animal with Consumer, Flyer {}
- Extension扩展
extension NumberParsing on String {
int parseInt() {
return int.parse(this);
}
}
print('21'.parseInt() * 2); // 42
作用域
// Hide "MyExtension" when importing types from
// "path/to/file.dart".
import 'path/to/file.dart' hide MyExtension;
// Only show "MyExtension" when importing types
// from "path/to/file.dart".
import 'path/to/file.dart' show MyExtension;
// The `shout()` method is only available within this
library.extension _Private on String {
String shout() => this.toUpperCase();
}
// 扩展中不能直接添加初始化方法,但是仍可返回类对象
extension SomePerson on Person {
static Person create(String firstName, String lastName) {
return Person(firstName, lastName);
}
}
- Override 重写
class SomePerson implements Person {
@override
void walk() => print('somebody walk');
}
TODO
Generics
Concurrency
Doc Comments
Libraries and visibility
语法层面
语言特性:连贯、简洁(语法层面的特性,一致性、高效、健壮编程)
核心库(丰富的跨平台库,高效编程)
如集合对象的(dart:collection),数学计算的 (dart:math), 编解码数据解析(dart:convert), 其他的commonly used packages
- 跨平台的库
- 原生库
- Web库
包管理(创建包、依赖管理)
项目开发(IDE、Debug、静态代码分析、测试等)
底层原理
-
Dart编译流程
-
Dart Analyzer