一、变量
二、数据类型
三、函数
四、操作符、运算符
五、流程控制
六、对象与类
七、异步请求
dart语言简易教程一
一个简单的dart 程序
// Define a function.
printNumber(num aNumber) {
print('The number is $aNumber.'); // Print to console.
}
// This is where the app starts executing.
main() {
var number = 42; // Declare and initialize a variable.
printNumber(number); // Call a function.
}
从这个程序里面我们可以看到如下的东西:
使用//来注释。同时/* ...*/也可以用来注释。
num 是一个数据类型,定义在语言中。同样的类型还有String,int,bool。
就是说Dart语言是有数据类型的概念的。
print() 是显示输出的方法。
'...'(或者"..."),表示是有个 string 类型的数据。
var 定义了一个变量,但是没有指定特定的数据类型。
按照Dart 的编程规范,使用2个空格来缩进。
这一点与java语言建议的4个空格不一样。
一些重要的概念
所有的东西都是对象,无论是变量,数字,函数等。
所以的对象都是类的实例。
所有的对像都继承自内置的Object类。程序中指定数据类型是为了指出自己的使用意图,并帮助语言进行语法检查。但是,指定类型不是必须的。
Dart 语言是弱数据类型。Dart 代码在运行前解析。
指定数据类型和编译时的常量,可以提高运行速度。Dart 程序有统一的程序入口: main()。
这一点是C / C++语言相像。Dart 没有public ,protected,and private的概念。
但是如果变量或函数以下划线(_)开始,则该函数或变量属于这个包私有(private)的方法。Dart 中变量或函数以下划线(_)或字母开始,后面接上任意组合的下划线( _ ),数字或字母。这点与大部分的编程语言是一样的。
Dart 的工具可以检查出警告信息(warning)和错误(errors)。
警告信息只是表明代码可能不工作,但是不会妨碍程序运行。
错误可以是编译时的错误,也可能是运行时的错误。编译的错误将阻止程序运行,运行时的错误将会以exception的方式呈现,这点与java捕获异常类似。Dart 使用 ; 来分割语句这点类似Java / C++
关键字
Dart 语言提供的关键字如下表所示:
1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|
abstract | continue | false | new | this |
as | default | final | null | throw |
assert | deferred | finally | operator | true |
async | do | for | part | try |
async | dynamic | get | rethrow | typedef |
await | else | if | return | var |
break | enum | implements | set | void |
case | export | import | static | while |
catch | external | in | super | with |
class | extends | is | switch | yield |
const | factory | library | sync | yield |
变量(Variable)
变量赋值的例子
// The variable called name contains a reference to a String object with a value of “Bob”.
var name = 'Bob';
默认值
没有初始化的变量都会被赋予默认值 null.
即使是数字也是如此, 因为在Dart 中数字也是一个对象。
int lineCount;
assert(lineCount == null);
// Variables (even if they will be numbers) are initially null.
```language
注意:assert()调用在生产模式中被忽略。在检查模式下,断言(条件)抛出异常,除非条件为真。
可选类型
也可以在定义的时候指定变量的类型。
String name = 'Bob';
指定数据类型可以更好的辨明自己的使用意图,编译器和IDE 工具可以根据这些类型信息来做检查,更早的发现问题。
如前文所说,通过指定类型,也可以减少编译和运行时间。
常量和固定值
如果定义的变量不会变化,可以使用 final 或 const来指明。
也可以使用final 或 *
const来代替类型声明。
final的值只能被设定一次。
const 是一个编译时的常量。( Const variables are implicitly final.)
final name = 'Bob'; // Or: final String name = 'Bob';
// name = 'Alice'; // Uncommenting this causes an error
通过对const类型做四则运算将自动得到一个const类型的值。
const bar = 1000000; // Unit of pressure (dynes/cm2)
const atm = 1.01325 * bar; // Standard atmosphere
```language
dart语言简易教程二
内建数据类型(Built-in types)
Dart 语言内建了下面集中类型
- numbers
- strings
- booleans
- lists (also known as arrays)
- maps
- runes (for expressing Unicode characters in a string)
- Number 类型
int
取值范围:-2^53 to 2^53
double
64 位长度的浮点型数据,符合IEEE 754 标准。
int 和 double 类型都是 num 类型的子类。
num 类型包括的操作包括: +, -, *, / 以及位移操作>>.
num 类型 有如下常用方法 abs(), ceil()和 floor()。完整的使用方法请参见:dart:math 包的使用说明。
int 类型不能包含小数点..
num类型操作例子:
// String -> int
var one = int.parse('1');
assert(one == 1);
// String -> double
var onePointOne = double.parse('1.1');
assert(onePointOne == 1.1);
// int -> String
String oneAsString = 1.toString();
assert(oneAsString == '1');
// double -> String
String piAsString = 3.14159.toStringAsFixed(2);
assert(piAsString == '3.14');
num 类型按位操作的例子:
assert((3 << 1) == 6); // 0011 << 1 == 0110
assert((3 >> 1) == 1); // 0011 >> 1 == 0001
assert((3 | 4) == 7); // 0011 | 0100 == 0111
Strings 类型
Dart 的String 是 UTF-16 编码的一个队列。
Dart语言定义的例子:
var s1 = 'Single quotes work well for string literals.';
var s2 = "Double quotes work just as well.";
var s3 = 'It\'s easy to escape the string delimiter.';
var s4 = "It's even easier to use the other delimiter.";
String 类型可以使用 + 操作:
var s1 = 'String ' 'concatenation'
" works even over line breaks.";
assert(s1 == 'String concatenation works even over '
'line breaks.');
var s2 = 'The + operator '
+ 'works, as well.';
assert(s2 == 'The + operator works, as well.');
可以使用三个‘ 或“来定义多行的String 类型。
var s1 = '''
You can create
multi-line strings like this one.
''';
var s2 = """This is also a
multi-line string.""";
可以使用r 来修饰String类型,表 表明是“raw” 类型字符串:
var s = r"In a raw string, even \n isn't special.";
String 类型可以在编译是才给String类型赋值。
// These work in a const string.
const aConstNum = 0;
const aConstBool = true;
const aConstString = 'a constant string';
// These do NOT work in a const string.
var aNum = 0;
var aBool = true;
var aString = 'a string';
const aConstList = const [1, 2, 3];
const validConstString = '$aConstNum $aConstBool $aConstString';
// const invalidConstString = '$aNum $aBool $aString $aConstList';
booleans 类型
Dart 的布尔类型名字是bool,可能的取值包括”ture“ 和 ”false“。
”bool“ 类型是 compile-time 的常量。
Dart 是强bool 类型检查,只有bool 类型的值是”true“ 才被认为是true。
var name = 'Bob';
if (name) {
// Prints in JavaScript, not in Dart.
print('You have a name!');
}
在production mode 中上面的代码将不会输出任何东西,因为name != true。
checked mode 中上面的代码将会出现异常,因为name不是bool 类型。
Lists 类型
在 Dart 语言中,具有一系列相同类型的数据被称为 List 对象。
Dart List 对象类似JavaScript 语言的 array 对象。
定义list的例子:
var list = [1, 2, 3];
Dart list 对象的第一个元素的位置是0,最后个元素的索引是list.lenght - 1。
var list = [1, 2, 3];
assert(list.length == 3);
assert(list[1] == 2);
list[1] = 1;
assert(list[1] == 1);
Maps 类型
Map 类型将keys 和 values 关联在一起。
keys 和 values 可以是任意类型的对象。
像其它支持Map 的编程语言一样,Map 的 key 必须是唯一的。
Map 对象的定义:
var gifts = {
// Keys Values
'first' : 'partridge',
'second': 'turtledoves',
'fifth' : 'golden rings'
};
var nobleGases = {
// Keys Values
2 : 'helium',
10: 'neon',
18: 'argon',
};
也可以使用Map 对象的构造函数 Map() 来创建Map 对象:
var gifts = new Map();
gifts['first'] = 'partridge';
gifts['second'] = 'turtledoves';
gifts['fifth'] = 'golden rings';
var nobleGases = new Map();
nobleGases[2] = 'helium';
nobleGases[10] = 'neon';
nobleGases[18] = 'argon';
添加新的key-value 对:
var gifts = {'first': 'partridge'};
assert(gifts['first'] == 'partridge');
检查key 是否在Map 对象中:
var gifts = {'first': 'partridge'};
assert(gifts['fifth'] == null);
使用.lenght 来获取key-value 对的数量:
var gifts = {'first': 'partridge'};
gifts['fourth'] = 'calling birds';
assert(gifts.length == 2);
Runes 类型
Dart 中 runes 是UTF-32字符集的string 对象。
codeUnitAt 和 codeUnit 用来获取UTF-16字符集的字符。
使用runes 来获取UTF-32字符集的字符。
main() {
var clapping = '\u{1f44f}';
print(clapping);
print(clapping.codeUnits);
print(clapping.runes.toList());
Runes input = new Runes(
'\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
上面例子的输出结果是:
[55357, 56399]
[128079]
Dart 语言简易教程(三)
函数(Functions)
Dart 是一个面向对象的语言,所以即使是函数也是对象,函数属于Function对象。
可以通过函数来指定变量或者像其它的函数传递参数。
函数实现的例子:
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
可以去掉形式参数数据类型和返回值的数据类型。
下面的例子演示了这些:
isNoble(atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
如果函数只有单个语句,可以采用简略的形式:
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
函数可以有两中类型的参数:
必须的
必须的参数放在参数列表的前面。可选的
可选的参数跟在必须的参数后面。
可选的参数
可以通过名字或位置指定可选参数。
函数调用:
enableFlags(bold: true, hidden: false);
可选的位置参数
将参数使用[] 括起来,用来表明是可选位置参数。
例如下面的例子,函数定义:
String say(String from, String msg, [String device]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
return result;
}
调用函数不包含第三个参数:
assert(say('Bob', 'Howdy') == 'Bob says Howdy');
调用函数包含第三个参数:
assert(say('Bob', 'Howdy', 'smoke signal') ==
'Bob says Howdy with a smoke signal');
参数默认值
可以定义包含默认位置参数或默认名字参数的函数。参数的默认值必须是编译时的静态值。
假如定义函数时,没有指定默认的参数值,则参数值默认为null 。
- 使用冒号(:)来设置默认名字参数。
// Sets the [bold] and [hidden] flags to the values you
// specify, defaulting to false.
enableFlags({bool bold: false, bool hidden: false}) {
// ...
}
// bold will be true; hidden will be false.
enableFlags(bold: true);
- 使用等号(
=
)来设置默位置字参数。
String say(String from, String msg,
[String device = 'carrier pigeon', String mood]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
if (mood != null) {
result = '$result (in a $mood mood)';
}
return result;
}
assert(say('Bob', 'Howdy') ==
'Bob says Howdy with a carrier pigeon');
也可以将lists 及maps类型作为默认值。
如下面的例子:
doStuff([List<int> list: const[1, 2, 3],
Map<String, String> gifts: const{'first': 'paper',
'second': 'cotton',
'third': 'leather'}]) {
print('list: $list');
print('gifts: $gifts');
}
main() {
// Use the default values for both parameters.
doStuff();
// Use the default values for the "gifts" parameter.
doStuff(list:[4,5,6]);
// Don't use the default values for either parameter.
doStuff(list: null, gifts: null);
}
对应输出结果是:
list: [1, 2, 3]
gifts: {first: paper, second: cotton, third: leather}
list: [4, 5, 6]
gifts: {first: paper, second: cotton, third: leather}
list: null
gifts: null
main() 函数
所以的APP 都必须有一个mian()函数,作为APP 的应用接入点。
main()函数返回void 类型,并且包含可选的List< String > 类型的参数。
main()函数不包含参数的例子:
void main() {
querySelector("#sample_text_id")
..text = "Click me!"
..onClick.listen(reverseText);
}
传递函数给函数
可以将一个函数作为一个参数传递给另一个函数。例如:
printElement(element) {
print(element);
}
var list = [1, 2, 3];
// Pass printElement as a parameter.
list.forEach(printElement);
//forEach传入list中的每一个值做为参数
也可以将函数赋值给一个变量。例如:
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
assert(loudify('hello') == '!!! HELLO !!!');
变量作用范围
嵌套的函数中可以访问包含他的函数中定义的变量。例如:
var topLevel = true;
main() {
var insideMain = true;
myFunction() {
var insideFunction = true;
nestedFunction() {
var insideNestedFunction = true;
assert(topLevel);
assert(insideMain);
assert(insideFunction);
assert(insideNestedFunction);
}
}
}
变量闭合
函数可以返回一个函数。例如:
/// Returns a function that adds [addBy] to the
/// function's argument.
Function makeAdder(num addBy) {
return (num i) => addBy + i;
}
main() {
// Create a function that adds 2.
var add2 = makeAdder(2);
// Create a function that adds 4.
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
函数返回值
所有的函数都会有返回值。
如果没有指定函数返回值,则默认的返回值是null。
没有返回值的函数,系统会在最后添加隐式的return 语句。
dart语言简易教程四
操作符与运算符
类型比较操作符
Dart 支持在运行时比较对象的类型,支持的操作如下:
Operator | Meaning |
---|---|
as | Typecast |
is | True if the object has the specified type |
is! | False if the object has the specified type |
is操作,用来比较前操作数是否是后操作数的对象。
as操作,用来将前操作数指定为后操作数的类型。
指定操作符
=操作符,将后操作数的值赋给前操作数。
??=操作符,如果前操作数是null类型,则将后操作数赋值给前操作数;如果前操作数不等于null,则保持前操作数的值发生变化。
级联操作符(..)
通过级联操作符(..),可以连续的操作同一对象,达到减少中间变量,减少代码的目的。
如下面的例子:
querySelector('#button') // Get an object.
..text = 'Confirm' // Use its members.
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
下面的代码与上面的例子实现功能完全相同:
var button = querySelector('#button');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
另一段例子:
final addressBook = (new AddressBookBuilder()
..name = 'jenny'
..email = 'jenny@example.com'
..phone = (new PhoneNumberBuilder()
..number = '415-555-0100'
..label = 'home')
.build())
.build();
简易教程五--流程控制
- if and else
- for loops
- while and do-while loops
- break and continue
- switch and case
- assert
- try-catch and throw
简易教程六
Dart 语言中类型是可选的,但是明确的指明使用的是泛型
如下面代码,泛型可以减少代码重复
代码片段一
abstract class ObjectCache {
Object getByKey(String key);
setByKey(String key, Object value);
}
代码片段二
abstract class StringCache {
String getByKey(String key);
setByKey(String key, String value);
}
以上的两段代码可以使用泛型简化如下:
abstract class Cache<T> {
T getByKey(String key);
setByKey(String key, T value);
}
库和可见性(Libraries and visibility)
使用import 和 library 机制可以方便的创建一个模块或分享代码。
一个Dart 库不仅能够提供相应的API,还可以包含一些以_开头的变量用于在库内部使用。
每一个Dart 应用都是一个库,即使它没有使用库机制。
库可以方便是使用各种类型的包。
引用库
通过import 语句在一个库中引用另一个库的文件。
import 的例子:
import 'dart:html';
在import语句后面需要接上库文件的路径。
对Dart 语言提供的库文件以dart:xx 格式
其它第三方的库文件使用package:xx格式
import 'dart:io';
import 'package:mylib/mylib.dart';
import 'package:utils/utils.dart';
指定一个库的前缀(Specifying a library prefix)
当引用的库拥有相互冲突的名字,可以为其中一个或几个指定不一样的前缀。
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// ...
Element element1 = new Element(); // Uses Element from lib1.
lib2.Element element2 = new lib2.Element(); // Uses Element from lib2.
引用库的一部分
如果只需要使用库的一部分内容,可以有选择的引用。
show 关键字:只引用一点
hide 关键字:除此之外都引用
例子如下:
// Import only foo.
import 'package:lib1/lib1.dart' show foo;
// Import all names EXCEPT foo.
import 'package:lib2/lib2.dart' hide foo;
延迟加载库(Deferred loading a library)
延迟加载机制,可以在需要使用的时候再加载库。
使用延迟加载库的原因:
减少应用启动时间
只加载必要的功能
为了实现延迟加载,必须使用deferred as 关键字。
import 'package:deferred/hello.dart' deferred as hello;
然后在需要使用的时候调用loadLibrary()方法。
greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
简易教程七--异步请求
Dart中没有线程的概念,只有isolate,每个isolate都是隔离的,并不会共享内存。
dart实现多线程的方式有两种
通过dart:async这个Lib中的API即可:
使用Future类,可以将任务加入到Event Queue的队尾通过isolate来实现