大家好,我是言淦,我今天带来的文章是《Dart十大特性速记》, 编程语言总是朝着轻便化前进, Dart也不例外,下面的内容来自官方文档以及自己的一些想法,希望能给你们带来帮助!
环境: Dart VM version: 2.3.0-dev.0.1
注: 本文所说的构造器等同于构造函数!
1.字符串插值(字符串运算+替换)
print('${3 + 2}') // '5'
print('${"word".toUpperCase()}') // 'WORD'
print('$myObject') // The value of myObject.toString()
2. ?? 和 ??= 运算符
”a ??= b“: 先判断变量 a 是否为 null,如果为 null 则将b的值赋予a,否则跳过;
”a ?? b“ 这里的a和b针对的是表达式, 当表达式a不为null, 返回a; 如果a为null, 返回b。其实 ?? 和 ??= 差不多, 只不过 ?? 第一个值为表达式,而 ??= 第一个值为变量。
“a ? b :c” 三元表达式
“?.” : 看下面的例子
int a; // Dart变量初始值为null,不为0或者其他值
a ??= 3;
print(a); // 3.
a ??= 5;
print(a); // a 的值仍然为 3.
print(1 ?? 3); // 打印 1.
print(null ?? 12); // 打印 12.
myObject?.someProperty
等价于
(myObject != null) ? myObject.someProperty : null
3.箭头函数(=>)
当函数的返回语句只有一句时,可以用箭头函数代替,算是 Dart 里面最常用的了
void main() {
void helloWorld() => print("hello world");
helloWorld();
/*
等价于
void helloWorld() {
print("hello world");
}
*/
}
4.级联器(..)
class Rectangle {
int width;
int height;
// 等价于 int area() => width * height;
int area() {
return this.width * this.height;
}
}
void main() {
// 初始化一个对象
Rectangle r = Rectangle()
..width = 10
..height = 20;
/*
等价于
Rectangle r = Rectangle();
r.width = 10;
r.height = 20;
*/
print(r.area()); // 200
print(r..area()); // Instance of 'Rectangle'
// 看不到东西,但实际上执行了area函数
Rectangle()
..width = 20
..height = 20
..area();
}
5.getter 和 setter选择器
class MyClass {
int _aProperty = 0;
int get aProperty => _aProperty;
set aProperty(int value) {
if (value >= 0) {
_aProperty = value;
}
}
}
等价于
class MyClass2 {
int _aProperty = 0;
int getAProperty() {
return _aProperty;
}
void setAProperty(int value) {
if (value >= 0) {
_aProperty = value;
}
}
}
6.可选参数
// Dart有两种形式的可选参数,第一种是可选位置参数,另一种是可选命名参数(用得比较多)
- 位置参数: [String param1, String param2]
- 命名参数: {String param1, String param2}
两者选其一
// 必选参数
int sum(int a, int b) {
return a + b;
}
print(sum(1, 2)); // 3
// 可选位置参数
int sum(int a, int b, [int c]) {
if (c != null) {
return a + b + c;
}
return a + b;
}
print(sum(1, 2)); // 3
print(sum(1, 2, 3)); // 6
// 可选命名参数
int sum(int a, int b, {int c}) {
if (c != null) {
return a + b + c;
}
return a + b;
}
print(sum(1, 2)); // 3
print(sum(1, 2, c: 3)); // 6
7.构造器简便写法
class MyColor {
int red;
int green;
int blue;
MyColor(this.red, this.green, this.blue);
/* 等价于
MyColor() {
this.red = red;
this.green = green;
this.blue = blue;
} */
}
final color = MyColor(80, 80, 128);
8.Initializer lists
不知道怎么翻译, 举了一个序列化和反序列化的例子
class User {
String user;
String pwd;
User();
// fromJson构造器,用于赋初值(Initializer lists), 并对传入的值进行校验(这部分可省略)
User.fromJson(Map<String, dynamic> json):
assert(json['user'] != ""), assert(json['pwd'] != ""),
user = json['user'], pwd = json['pwd'];
/*
等价于
static User fromJson(Map<String, dynamic> json){
User u = new User();
u.user = json['user'];
u.pwd = json['pwd'];
return u;
}
*/
// 这个例子其实就是Dart中json数据的序列化和反序列化, fromJson是序列化,toJson是反序列化
Map<String, dynamic> toJson() => {
'user': user,
'pwd': pwd,
};
/*
等价于
Map<String, dynamic> toJson() {
var map = new Map<String, dynamic>();
map['user'] = user;
map['pwd'] = pwd;
return map;
}
};
*/
}
void main() {
Map<String, dynamic> testData = {'user': 'aa', 'pwd': 'bb'};
User u = User.fromJson(testData);
print(u); // Instance of 'User'
Map testDataR = u.toJson();
print(testDataR); // {user: aa, pwd: bb}
}
9.命名构造器(Named constructors)
初看时,其实不明白为什么叫命令构造器,官方文档只解释说“命名构造器的作用是为了让一个类有多个构造器”。不过看久了就发现,
我们可以通过"类名.自定义名" 来创建构造器, 如下面的 Point.origin(), Point.helloWorld(), 你想定义什么名字就什么名字,这才明白命名构造器的含义。
class Point {
num x, y;
Point({this.x, this.y}); // 与官方文档不同
Point.origin() {
x = 0;
y = 0;
}
Point.helloWorld() {
x = 1;
y = 1;
}
}
final myPoint1 = Point();
final myPoint2 = Point.origin();
print(myPoint1.x); // null
print(myPoint2.y); // 0
10.工厂构造器(Factory constructors)
// Java的工厂模式
public interface Shape {
void draw();
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
public class ShapeFactory {
//使用 getShape 方法获取形状类型的对象
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("circle")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("square")){
return new Square();
}
return null;
}
}
public class FactoryPatternDemo {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
//获取 Circle 的对象,并调用它的 draw 方法
Shape shape1 = shapeFactory.getShape("circle");
shape1.draw();
//获取 Square 的对象,并调用它的 draw 方法
Shape shape3 = shapeFactory.getShape("square");
shape3.draw();
}
}
// Dart 的工厂模式
// 比Java的更简洁, 但思想不变,其中Shape.fromTypeName可以自定义为其他名字,比如Shape.fromType
class Square extends Shape {
@override
void draw() => print("Inside Square::draw() method.");
}
class Circle extends Shape {
void draw() => print("Inside Circle::draw() method.");
}
class Shape {
Shape();
void draw(){}
factory Shape.fromTypeName(String typeName) {
if (typeName == 'square') return Square();
if (typeName == 'circle') return Circle();
print('I don\'t recognize $typeName');
return null;
}
}
Shape shape = Shape();
shape.draw();
Shape square = Shape.fromTypeName('square');
square.draw();
结尾
Dart的构造器真的是非常多, 其中还有 Redirecting constructors(B构造器重定向到A构造器) 和 Const constructors, 就请读者查看官方文档了,链接在最上面(狗手动头)。