类、枚举、typedef和类型参数
class SliderMenu { ... }
class HttpRequest { ... }
typedef Predicate = bool Function(T value);
包括用于元数据注释的类
class Foo {
const Foo([arg]);
}
@Foo(anArg)
class A { ... }
@Foo()
class B { ... }
library peg_parser.source_scanner;
import 'file_system.dart';
import 'slider_menu.dart';
不推荐如下写法:
library pegparser.SourceScanner;
import 'file-system.dart';
import 'SliderMenu.dart';
import 'dart:math' as math;
import 'package:angular_components/angular_components'
as angular_components;
import 'package:js/js.dart' as js;
不推荐如下写法:
import 'dart:math' as Math;
import 'package:angular_components/angular_components'
as angularComponents;
import 'package:js/js.dart' as JS;
var item;
HttpRequest httpRequest;
void align(bool clearItems) {
// ...
}
const pi = 3.14;
const defaultTimeout = 1000;
final urlScheme = RegExp('^([a-z]+):');
class Dice {
static final numberGenerator = Random();
}
不推荐如下写法:
const PI = 3.14;
const DefaultTimeout = 1000;
final URL_SCHEME = RegExp('^([a-z]+):');
class Dice {
static final NUMBER_GENERATOR = Random();
}
因为Dart可以告诉您声明的类型、范围、可变性和其他属性,所以没有理由将这些属性编码为标识符名称。
defaultTimeout
不推荐如下写法:
kDefaultTimeout
为了使你的文件前言保持整洁,我们有规定的命令,指示应该出现在其中。每个“部分”应该用空行分隔。
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';
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
import 'package:my_package/util.dart';
import 'src/error.dart';
import 'src/foo_bar.dart';
export 'src/error.dart';
不推荐如下写法:
import 'src/error.dart';
export 'src/error.dart';
import 'src/foo_bar.dart';
这样做可以避免悬浮的else问题
if (isWeekDay) {
print('Bike to work!');
} else {
print('Go dancing or read a book!');
}
一个if语句没有else子句,其中整个if语句和then主体都适合一行。在这种情况下,如果你喜欢的话,你可以去掉大括号
if (arg == null) return defaultValue;
如果流程体超出了一行需要分划请使用大括号:
if (overflowChars != other.overflowChars) {
return overflowChars < other.overflowChars;
}
不推荐如下写法:
if (overflowChars != other.overflowChars)
return overflowChars < other.overflowChars;
除非是区分大小写的标识符,否则第一个单词要大写。以句号结尾(或“!”或“?”)。对于所有的注释都是如此:doc注释、内联内容,甚至TODOs。即使是一个句子片段。
greet(name) {
// Assume we have a valid name.
print('Hi, $name!');
}
不推荐如下写法:
greet(name) {
/* Assume we have a valid name. */
print('Hi, $name!');
}
可以使用块注释(/…/)临时注释掉一段代码,但是所有其他注释都应该使用//
使用///文档注释来记录成员和类型。
使用doc注释而不是常规注释,可以让dartdoc找到并生成文档。
/// The number of characters in this chunk when unsplit.
int get length => ...
由于历史原因,达特茅斯学院支持道格评论的两种语法:///(“C#风格”)和/**…* /(“JavaDoc风格”)。我们更喜欢/// 因为它更紧凑。/*和/在多行文档注释中添加两个无内容的行。在某些情况下,///语法也更容易阅读,例如文档注释包含使用*标记列表项的项目符号列表。
Doc注释并不仅仅针对库的公共API的外部使用者。它们还有助于理解从库的其他部分调用的私有成员
以简短的、以用户为中心的描述开始你的文档注释,以句号结尾。
/// Deletes the file at [path] from the file system.
void delete(String path) {
...
}
不推荐如下写法:
/// Depending on the state of the file system and the user's permissions,
/// certain operations may or may not be possible. If there is no file at
/// [path] or it can't be accessed, this function throws either [IOError]
/// or [PermissionError], respectively. Otherwise, this deletes the file.
void delete(String path) {
...
}
在第一个句子之后添加一个空行,把它分成自己的段落
/// Deletes the file at [path].
///
/// Throws an [IOError] if the file could not be found. Throws a
/// [PermissionError] if the file is present but could not be deleted.
void delete(String path) {
...
}
flutter go 中,导入lib下文件库,统一指定包名,避免过多的../../
package:flutter_go/
如果有两个字符串字面值(不是值,而是实际引用的字面值),则不需要使用+连接它们。就像在C和c++中,简单地把它们放在一起就能做到。这是创建一个长字符串很好的方法但是不适用于单独一行。
raiseAlarm(
'ERROR: Parts of the spaceship are on fire. Other '
'parts are overrun by martians. Unclear which are which.');
不推荐如下写法:
raiseAlarm('ERROR: Parts of the spaceship are on fire. Other ' +
'parts are overrun by martians. Unclear which are which.');
'Hello, $name! You are ${year - birth} years old.';
'Hi, $name!'
"Wear your wildest $decade's outfit."
不推荐如下写法:
'Hello, ' + name + '! You are ' + (year - birth).toString() + ' y...';
不推荐如下写法:
'Hi, ${name}!'
"Wear your wildest ${decade}'s outfit."
如果要创建一个不可增长的列表,或者其他一些自定义集合类型,那么无论如何,都要使用构造函数。
var points = [];
var addresses = {};
var lines = [];
不推荐如下写法:
var points = List();
var addresses = Map();
if (lunchBox.isEmpty) return 'so hungry...';
if (words.isNotEmpty) return words.join(' ');
不推荐如下写法:
if (lunchBox.length == 0) return 'so hungry...';
if (!words.isEmpty) return words.join(' ');
如果有一个集合,并且希望从中生成一个新的修改后的集合,那么使用.map()、.where()和Iterable上的其他方便的方法通常更短,也更具有声明性
var aquaticNames = animals
.where((animal) => animal.isAquatic)
.map((animal) => animal.name);
在Dart中,如果你想遍历一个序列,惯用的方法是使用循环。
for (var person in people) {
...
}
不推荐如下写法:
people.forEach((person) {
...
});
给定一个迭代,有两种明显的方法可以生成包含相同元素的新列表
var copy1 = iterable.toList();
var copy2 = List.from(iterable);
明显的区别是第一个比较短。重要的区别是第一个保留了原始对象的类型参数
// Creates a List:
var iterable = [1, 2, 3];
// Prints "List":
print(iterable.toList().runtimeType);
// Creates a List:
var iterable = [1, 2, 3];
// Prints "List":
print(List.from(iterable).runtimeType);
由于遗留原因,Dart均允许“:”和“=”作为指定参数的默认值分隔符。为了与可选的位置参数保持一致,使用“=”。
void insert(Object item, {int at = 0}) { ... }
不推荐如下写法:
void insert(Object item, {int at: 0}) { ... }
如果参数是可选的,但没有给它一个默认值,则语言隐式地使用null作为默认值,因此不需要编写它
void error([String message]) {
stderr.write(message ?? '\n');
}
不推荐如下写法:
void error([String message = null]) {
stderr.write(message ?? '\n');
}
在Dart中,未显式初始化的变量或字段自动被初始化为null。不要多余赋值null
int _nextId;
class LazyId {
int _id;
int get id {
if (_nextId == null) _nextId = 0;
if (_id == null) _id = _nextId++;
return _id;
}
}
不推荐如下写法:
int _nextId = null;
class LazyId {
int _id = null;
int get id {
if (_nextId == null) _nextId = 0;
if (_id == null) _id = _nextId++;
return _id;
}
}
在设计类时,您通常希望将多个视图公开到相同的底层状态。通常你会看到在构造函数中计算所有视图的代码,然后存储它们:
应该避免的写法:
class Circle {
num radius;
num area;
num circumference;
Circle(num radius)
: radius = radius,
area = pi * radius * radius,
circumference = pi * 2.0 * radius;
}
如上代码问题:
推荐的写法如下:
class Circle {
num radius;
Circle(this.radius);
num get area => pi * radius * radius;
num get circumference => pi * 2.0 * radius;
}
不推荐如下写法:
class Box {
var _contents;
get contents => _contents;
set contents(value) {
_contents = value;
}
}
尤其对于 StatelessWidget
不推荐如下写法:
class Box {
var value;
void clear() {
this.update(null);
}
void update(value) {
this.value = value;
}
}
推荐如下写法:
class Box {
var value;
void clear() {
update(null);
}
void update(value) {
this.value = value;
}
}
不推荐如下写法:
class Point {
num x, y;
Point(num x, num y) {
this.x = x;
this.y = y;
}
}
推荐如下写法:
class Point {
num x, y;
Point(this.x, this.y);
}
Dart2使new 关键字可选
推荐写法:
Widget build(BuildContext context) {
return Row(
children: [
RaisedButton(
child: Text('Increment'),
),
Text('Click!'),
],
);
}
不推荐如下写法:
Widget build(BuildContext context) {
return new Row(
children: [
new RaisedButton(
child: new Text('Increment'),
),
new Text('Click!'),
],
);
}
async/await语法提高了可读性,允许你在异步代码中使用所有Dart控制流结构。
Future countActivePlayers(String teamName) async {
try {
var team = await downloadTeam(teamName);
if (team == null) return 0;
var players = await team.roster;
return players.where((player) => player.isActive).length;
} catch (e) {
log.error(e);
return 0;
}
}
如果可以在不改变函数行为的情况下省略异步,那么就这样做。、
Future afterTwoThings(Future first, Future second) {
return Future.wait([first, second]);
}
不推荐写法:
Future afterTwoThings(Future first, Future second) async {
return Future.wait([first, second]);
}
Panda-MBP:panda_first panda8z$ flutter run
No connected devices.
Run 'flutter emulators' to list and start any available device emulators.
If you expected your device to be detected, please run "flutter doctor" to diagnose
potential issues, or visit https://flutter.io/setup/ for troubleshooting tips.
Panda-MBP:panda_first panda8z$ flutter emulators
2 available emulators:
Pixel_2_API_28 • pixel_2 • Google • Pixel 2 API 28
apple_ios_simulator • iOS Simulator • Apple
To run an emulator, run 'flutter emulators --launch ' .
To create a new emulator, run 'flutter emulators --create [--name xyz]'.
You can find more information on managing emulators at the links below:
https://developer.android.com/studio/run/managing-avds
https://developer.android.com/studio/command-line/avdmanager
Panda-MBP:panda_first panda8z$ flutter emulators --launch apple_ios_simulator
Panda-MBP:panda_first panda8z$ flutter run
Launching lib/main.dart on iPhone X in debug mode...
Running Xcode build... ⣟ (This is taking an unex
├─Assembling Flutter resources... 1.4s
└─Compiling, linking and signing... 8.5s
Xcode build done. 12.3s
Syncing files to device iPhone X... 1,741ms
? To hot reload changes while running, press "r". To hot restart (and rebuild state), press
"R".
An Observatory debugger and profiler on iPhone X is available at: http://127.0.0.1:56973/
For a more detailed help message, press "h". To detach, press "d"; to quit, press "q".
Application finished.
Panda-MBP:panda_first panda8z$ flutter
官网说的方法:
Fetch data from the internet - Flutter
通过dart包管理网站查看包的最新版本号:
http | Dart Package
flutter packages get
命令 安装http依赖main.dart
文件的内容,改成下面的代码import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future fetchPost() async { // 这个方法是个异步方法,返回Future类型的值
final response =
await http.get('https://jsonplaceholder.typicode.com/posts/1');
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
return Post.fromJson(json.decode(response.body));
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
/// 数据modle
class Post {
final int userId;
final int id;
final String title;
final String body;
Post({this.userId, this.id, this.title, this.body});//初始化方法
factory Post.fromJson(Map json) {
return Post(
userId: json['userId'],
id: json['id'],
title: json['title'],
body: json['body'],
);
}
}
void main() => runApp(MyApp(post: fetchPost()));
class MyApp extends StatelessWidget {
final Future post;
MyApp({Key key, this.post}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: Center(
child: FutureBuilder(
future: post,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.title);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner
return CircularProgressIndicator();
},
),
),
),
);
}
}
flutter run
Panda-MBP:panda_first panda8z$ flutter run
No connected devices.
Run 'flutter emulators' to list and start any available device emulators.
If you expected your device to be detected, please run "flutter doctor" to diagnose
potential issues, or visit https://flutter.io/setup/ for troubleshooting tips.
Panda-MBP:panda_first panda8z$ flutter emulators
2 available emulators:
Pixel_2_API_28 • pixel_2 • Google • Pixel 2 API 28
apple_ios_simulator • iOS Simulator • Apple
To run an emulator, run 'flutter emulators --launch ' .
To create a new emulator, run 'flutter emulators --create [--name xyz]'.
You can find more information on managing emulators at the links below:
https://developer.android.com/studio/run/managing-avds
https://developer.android.com/studio/command-line/avdmanager
Panda-MBP:panda_first panda8z$ flutter emulators --launch apple_ios_simulator
Panda-MBP:panda_first panda8z$ flutter run
Launching lib/main.dart on iPhone X in debug mode...
Running Xcode build... ⣟ (This is taking an unex
├─Assembling Flutter resources... 1.4s
└─Compiling, linking and signing... 8.5s
Xcode build done. 12.3s
Syncing files to device iPhone X... 1,741ms
? To hot reload changes while running, press "r". To hot restart (and rebuild state), press
"R".
An Observatory debugger and profiler on iPhone X is available at: http://127.0.0.1:56973/
For a more detailed help message, press "h". To detach, press "d"; to quit, press "q".
Application finished.
Panda-MBP:panda_first panda8z$ flutter run
Your application could not be compiled, because its dependencies could not be established.
The following Dart file:
/Users/panda8z/panda/git4me/PandaFlutter/panda_first/lib/main.dart
...refers, in an import, to the following library:
package:http/http.dart
That library is in a package that is not known. Maybe you forgot to mention it in your pubspec.yaml file?
Panda-MBP:panda_first panda8z$ flutter packages get
Running "flutter packages get" in panda_first... 0.5s
Panda-MBP:panda_first panda8z$ flutter run
Your application could not be compiled, because its dependencies could not be established.
The following Dart file:
/Users/panda8z/panda/git4me/PandaFlutter/panda_first/lib/main.dart
...refers, in an import, to the following library:
package:http/http.dart
That library is in a package that is not known. Maybe you forgot to mention it in your pubspec.yaml file?
Panda-MBP:panda_first panda8z$ flutter packages get
Running "flutter packages get" in panda_first... 6.8s
Panda-MBP:panda_first panda8z$ flutter packages get
Error on line 20, column 9 of pubspec.yaml: Invalid version constraint: Expected version number after "<" in "" , got "latest_version>".
http: <latest_version>
^^^^^^^^^^^^^^^^
Running "flutter packages get" in panda_first...
pub get failed (65)
Panda-MBP:panda_first panda8z$ flutter packages get
Running "flutter packages get" in panda_first... 1.3s
Panda-MBP:panda_first panda8z$ flutter run
Launching lib/main.dart on iPhone X in debug mode...