0%

dart学习之路(一)

dart 语言学习之路:数据类型和函数

注释

1
2
3
4
5
6
7
8
9
10
11
// 单行注释

/*
* 多行注释
*/

/**
* 文档注释
*/

/// Dart特有的文档注释

数据类型

Number 类型

基本类型有两种:整型 int 和 浮点型double

整型的范围是 2^63-1-2^63 ,如需编译成 js ,那么整型的范围就是 2^53-1-2^53

浮点型是 64 位的数字,包括小数位数,并符合IEEE754标准。一个数字只要有小数点,就是 double 类型。

1
2
3
4
int num1 = 12;
int num2 = 0xEABDF;
double num3 = 12.0;
double num4 = 1.2e10;

dart 2.1 开始,必要的时候两种类型可以自动转换。
如:double z = 1; 相当于 double z = 1.0

数字类型字面量是编译时常量。 在算术表达式中,只要参与计算的因子是编译时常量, 那么算术表达式的结果也是编译时常量。

1
2
3
const ps = 1000;
const sur = 5;
const ur = sur * ps;

String 类型

字符串类型是使用 Unicode-16 存储,可以使用单引号或双引号定义。

字符串内部可以使用 ${expression} 来使用变量或表达式(当仅取变量值时,可以省略花括号),类似 js 模板字符串。

定义多行字符串需要使用三个引号。

在字符串里的一些转义字符不想被表达,需要在字符串前添加 r 表示是一个原始字符串。

1
2
3
4
5
6
7
8
String str = 'Silen';
String str1 = '''
123
abc
321''';
String str2 = 'Hello ${str.toLowerCase()}'; // Hello silen
String str21 = 'Hello $str'; // Hello silen
String str3 = r'Hello \n World';

字符串连接可以使用 + 操作符,相邻的字符串在编译的时候会自动连接。如果多个字符串相邻,中间的字符串不能为空,否则报错。但是如果单引号和双引号相邻,即使是空值也不会报错,但相信没有人这么做

1
2
3
String s1 = 'silen' + ' yang'; // silen yang
String s2 = 'silen'' ''yang'; // silen yang
String s3 = 'silen'""'yang'; // silenyang

Boolean 类型

1
bool bo = false;

List 类型(数组)

数组类型,可以指定数组元素的类型

1
2
3
List arr1 = [1, 2, 3, 4];
List<String> arr2 = ['12', 'abc'];
List<dynamic> arr3 = [12, 'abc'];

Map 类型

1
2
3
Map obj = (new) Map();
obj['name'] = 'silen';
obj['age'] = 10;

Set 类型

与 js 中的 Set 一致,值是唯一的

1
2
3
4
5
6
var names = {}; // 空集合
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
集合操作,加入一个元素或者集合
var elements = <String>{};
elements.add('fluorine');
elements.addAll(halogens);

Runes 类型

dart 中 使用 runes 来获取 UTF-32 字符集的字符,可以通过文字转换成符号表情或者代表特定的文字。

String 的 codeUnitAtcodeUnit 属性可以获取 UTF-16 字符集的字符

1
2
3
4
5
6
7
8
var clapping = '\u{1f44f}';
String clapping = '\u{1f44f}';
print(clapping); // 👏
print(clapping.codeUnits); // [55357, 56399]
print(clapping.runes.toList()); // [128079]

Runes input = (new) Runes('\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
print(String.fromCharCodes(input)); // ♥ 😅 😎 👻 🖖 👍

Symbol 类型

1
2
3
4
Symbol sy1 = (new) Symbol('name');
Symbol sy2 = #name;

print(sy1 == sy2); // true

类型转换

所有非字符串类型都可以使用 toString() 转换为字符串。

数字(num)类型的字符串可以使用对应类型的 parse 姜字符串转换为相应的数字。

1
2
3
4
5
6
7
8
9
10
11
String si = '12';
String sd = '1.2';
int i = 12;
double d = 1.2;
bool b = false;

print(double.parse(sd));
print(int.parse(si));
print(i.toString());
print(d.toString());
print(b.toString());

类型判断

在 dart 中,类型的判断使用 isis! 来判断变量的类型。

  • is 判断一个变量是不是某个类型的数据
  • is! 判断变量不是某个类型的数据
1
2
3
4
var s = '123';
print(s is String); // true
var num = 12;
print(s is! String); // true

若一个类型能够转换为另一个类型,可以使用 as 来直接进行类型转换。

1
2
3
4
5
if(person is Person){ // 类型检测,转换之前用is判断一下
person.age=18;
}

(person as Person).age=18;

变量

变量的声明除了使用具体的类型,还可以使用 var 来声明。它会根据初始化的只判断什么类型,一旦确定不可更改。

所有的类型都为对象 。所以变量没有初始值时,默认为 null

1
2
3
4
5
6
var str = '12';

str = 12; // A value of type 'int' can't be assigned to a variable of type 'String'.

var num;
print(num == null); // true

如果变量类型是动态变化的,使用 dynamicObject 来声明。

1
2
3
4
5
6
7
dynamic a = "Silen";
// or
Object a = 'silen';

print(a is String); // true
a = 123;
print(a is int); // true

常量

常量可以使用 finalconst 来声明。都可以做类型推导,与 var 的使用一致,但不能混用。
finalconst 修饰的变量,变量类型可以省略,建议指定数据类型。

1
2
3
4
final num1 = 12;
final int num2 = 12;
const str1 = '12';
const String str2 = '12';

区别:

  1. const 定义的是编译时常量,只能用常量来初始化
  2. final 定义的运行时常量,可以用变量来初始化
  3. 可以通过 const 来创建常量的值,就是说 const[] 本身是构造函数

var、final 等在左边定义变量的时候,并不关心右边是不是常量
但是如果右边用了 const,那么不管左边如何,右边都必须是常量

1
2
3
4
5
6
const list = const[1,2,3]; // Ok
const list = [1,2,3]; // OK,定义不可变列表

final list = [1,2,3]; // Ok
final list = const[1,2,3]; // Ok
final list = const[new DateTime.now(),2,3]; // Error,const右边必须是常量

常量如果是类级别的,请使用 static const

const 关键字不只是声明常数变量,您也可以使用它来创建常量值,以及声明创建常量值的构造函数,任何变量都可以有一个常量值。

1
2
3
4
5
6
7
// const []创建一个空的、不可变的列表(EIL)。
var varList = const []; // varList 当前是一个EIL
final finalList = const []; // finalList一直是EIL
const constList = const []; // constList 是一个编译时常量的EIL

// 可以更改非final,非const变量的值,即使它曾经具有const值
varList = ["haha"];

函数

函数也是对象,当没有指定返回值的时候,函数默认返回 null

定义方法如下:

1
2
3
4
String sayHello(String name)
{
return 'Hello $name!';
}

类型是可选,可以省略显式的类型,但仍然建议显式指定类型

1
2
3
4
sayHello(name)
{
return 'Hello $name!';
}

assert() 断言函数

Debug 模式下,当表达式的值为 false 时抛出异常。第二个参数 message,用于在抛出异常的时候,输出具体信息。

1
2
String s = '12';
assert(s is String, '不是String类型');

箭头函数

如果函数只是简单的返回一个表达式的值可以使用箭头函数

1
sayHello(name) => 'hello $name';

匿名函数

1
2
3
4
5
6
([[Type] param1[, …]]) {
codeBlock;
};

// 例如:
var sayHello = (name) => 'hello $name';

可选参数与默认值

可选参数有两种,但两种不能同时使用。

  • 命名可选参数使用大括号 {},默认值用冒号 :=
  • 位置可选参数使用方括号 [],默认值用等号 =
命名参数

命名参数, 定义函数时,使用 {param1, param2, …},用于指定命名参数。在调用的时候需要指明参数名,没有赋值的参数值为 null。例如:

1
2
3
4
5
6
7
8
9
10
void fun({bool a, bool b}) {
print(a && b);
}
fun(a: true, b: false); // false

// 默认值
void fun({bool a: false, bool b = true}) {
print(a && b);
}
fun(a: true); // true
位置参数

位置参数,用 [] 它们标记为可选的位置参数, 在调用的时候参数值会依次按顺序赋值,没有赋值的参数值为 null。:

1
2
3
4
5
6
7
8
9
10
void fun(String a, [String b, String c]) {
print('$a $b $c');
}
fun('a', 'b'); // a b null

// 默认值
void fun(String a, [String b, String c = 'c']) {
print('$a $b $c');
}
fun('a', 'b'); // a b c

主函数

这是 dart 程序执行的入口,返回 void,并具有可选的 List<String> 作为参数。

1
2
3
(void) main {
print('hello world');
}

作用域

作用域 是由代码的布局静态决定的。

闭包

闭包 是一个函数对象,它可以访问其词法作用域内的变量,就算该函数是在其原始作用域之外使用的。