阅读 1313

Dart tips for Flutter

本文翻译自 Code With Andrea 的一个名为 《Dart & Flutter Easy Wins》的文章集,主要分享一些 Dart for Flutter 语言层面上的小技巧。这些技巧能够帮助大家写出精简、高效、符合 Google 标准的代码,会不定期更新。

language

const final var

尽量使用 const,如果不行就使用 final,最后才考虑 var。

const text = 'I am a doctor.';
复制代码

使用类型声明

对范型类型进行类型声明,使代码更安全

const ciyies = <String>['Lodon', 'Beijing', 15];
复制代码

未使用参数使用 _ 声明

MaterialPageRoute(
    builder: (_) => DetailPage(),
);
复制代码

使用 collection-ifspreads

final restaurant = {
    'name': 'Pizza',
    'cuisine': 'Italian',
    if (addRatings) ...{
        'avaRatting': avgRatting,
        'numRattings': numRattings,
    }
}
复制代码

使用 .. 对变量进行连续多次调用

final path = Path()
  ..moveTo(0,0)
  ..moveTo(1,0)
  ..moveTo(0,1)
复制代码

使用 catch on 捕获不同类型的错误

try {
	await authScerice.signInAnonymously();
} on PlatformException catch (e) {
  // handle PlatformException
} on SocketException catch (e) {
	// handle SocketException
} catch (e) {
	// handle everything
}
复制代码

重写 toString 提升 debug 体验

class Point { 
  const Point(this.x, this.y);
	final num x;
	final num y;
  @override
  String toString() => '($x, $y)';
}

print(Point(1, 2));
复制代码

使用 ?? 返回非 null

final value = list[4] ?? 0;
复制代码

使用 """ 输入多行文本

print("""
This is a short sentence.
This is an other short sentence.
""");
复制代码

使用 ... 快速实现 list 浅拷贝

const list = [1, 2, 3];
final copy = [...list];
复制代码

使用 ? 避免对 null 调用方法

someClass?.call();
复制代码

通过实现 call 方法,让类可以像方法一样调用

class PasswordValidator {
	bool call(String password) {
		return password.length > 10;
  }
}
void main() {
	final validator = PasswordValidator();
	validator('test'); // false
	validator('test1234'); // false validator('not-so-frozen-arctic'); // true
}
复制代码

使用 Future.wait 同时执行多个异步方法

class CovidAPI {
	Future<int> getCases() => Future.value(1000);
	Future<int> getRecovered()
	Future.value(100);
	Future<int> getDeaths() => Future.value(10);
}
void main() async {
	final api = CovidAPI();
	final values = await Future.wait([
		api.getCases(),
		api.getRecovered(),
		api.getDeaths()
	1]);
	print(values); // [1000, 100, 10]
}
复制代码

使用 show hide 隐藏引入包的部分 API

// shows Stream only
import 'dart :async' show Stream;
// shows all but StreamController
import 'dart :async' hide StreamController;
复制代码

使用 as 解决包命名冲突

import 'package:http/http.dart' as http;
复制代码

使用 toStringAsFixed 格式化 float

const x= 12.34567;
print(x.toString());
// 12.34567
print(x.toStringAsFixed(3));
// 12.346 (3 decimal digits)
复制代码

StringInt 可以相乘

for (var i= 1; i <= 5; i++) {
	print('😄' * i);
}
// Output:
😄
😄😄
😄😄😄
😄😄😄😄
😄😄😄😄😄
复制代码

使用命名构造函数,创建多个构造函数

class Complex {
  final double re;
  final double im;
  Complex(this.re, this.im);
  
  Complex.real(this.re): im = 0;
}
复制代码

使用工厂构造函数而不是静态方法

The difference between a "factory constructor" and a "static method"

class Item {
	final String itemId;
	final double price;
	item({required this.itemId, required this.price});
	factory Item.fromJson(Map<String, dynamic> json) { 
    	return Item(
			itemId: json['itemId'] as String,
			price: json['price'] as double,
      	);
  	}
	static Item fromMap(Map-String, dynamic> json) { 
    	return Item(
			itemId: json['itemId'] as String,
			price: json['price'] as double,
    	);
  	}
}
复制代码

单例

class Singleton {
  Singleton._();
  static final instance = Singleton._();
}
复制代码

考虑使用 set

final citiesSet = {'London', 'Beijin', 'Rome'};
复制代码

安全地遍历 map

for (final entry in activeties.entries) {
  print('${entry.key}:${entry.value}');
}
复制代码

根据平台导入不同的文件

// stub implementation
import 'copy_to_clipboard_stub.dart'
// dart:html implementation
if (dart.library.html) 'copy_to_clipboard_web.dart'
// dart:io implementation
if (dart.library.io) 'copy_to_clipboard_non_web. dart';
复制代码

get set 方法

double celsius;
double get farenheit => celsius * 1.8 + 32;
set farenheit(double degrees) => celsius = (degrees-32) / 1.8;
复制代码

延迟执行

await Future.delayed(Duration(seconds: 2));
	// Return mock result return 100;
}
复制代码

assert 中断

assert(url.startsWith('https'))
复制代码

使用 Never 构建一个没有返回的函数

// this function can never return, only throw
Never wrongType(String type, Object value) {
	throw ArgumentError('Expected $type, but was ${value.runtimeType}.');
}
复制代码

package

equatable

快速实现 hashCode == toString

import 'package:equatable/equatable.dart';
class Person extends Equatable { 
  final String name;
	Person(this.name);
  
	@override
	List<object> get props => [name];
  
	@override
	bool get stringify => true;
}
复制代码

dartx

更优雅的使用 date 和 time

print(5.seconds); // 0:00:05.000000 
print(2.minutes); // 0:02:00.000000 
print(1.hours.inSeconds); // 3600
复制代码

logger

加强版日志