变量
所有变量引用的都是对象,每个对象都是一个类的实例。数字、函数以及 null 都是对象。除去 null 以外(如果你开启了 空安全), 所有的类都继承于 Object 类。
尽管 Dart 是强类型语言,但是在声明变量时指定类型是可选的,因为 Dart 可以进行类型推断。
默认值
在 Dart 中,未初始化以及可空类型的变量拥有一个默认的初始值 null。
int? lineCount;
即便数字也是如此,因为在Dart中一切皆为对象,数字也不例外。
延时变量(Late variables)
- 延时初始化变量
- 声明一个非空变量,在声明后初始化。
late String description;
void main() {
description = '延时变量';
print(description);
}
变量使用时,才初始化:
late String temperature = readThermometer();
var
var可以接收任何类型的变量,但var变量一旦赋值,类型便会确定,则不能再改变其类型。
void main() {
var str = "hi world";
// 下面代码在dart中会报错,因为变量t的类型已经确定为String,
// 类型一旦确定后则不能再更改其类型。
str = 1;
}
Object
Object是Dart所有对象的根基类,也就是说在Dart中所有类型都是Object的子类(包括Function和Null),所以任何类型的数据都可以赋值给Object声明的对象。Object声明的变量可以赋值任意对象,且后期可以改变赋值的类型。
void main() {
Object o="I am basice class";
o=1;
dynamic d;
d=1;
d="this is String ";
}
dynamic
dynamic声明的变量可以赋值任意对象,且后期可以改变赋值的类型。dynamic与Object不同的是dynamic声明的对象编译器会提供所有可能的组合,而Object声明的对象只能使用 Object 的属性与方法, 否则编译器会报错。
void main() {
Object o="I am basice class";
// 报错:The getter 'length' isn't defined for the class 'Object'.
print(o.length);
dynamic d="this is String ";;
print(d.length);
}
final和const
如果你不想更改一个变量,可以使用关键字 final 或者 const 修饰变量,这两个关键字可以替代var关键字或者加在一个具体的类型前。
- 一个 final 变量只可以被赋值一次;一个const变量是一个编译时常量(const 变量同时也是 final 的)。
- 顶层的 final变量或者类的final变量在其第一次使用的时候被初始化。
void main() {
//可以省略String这个类型声明 等同于 final String str = "hi world";
final str = "hi world";
//可以省略String这个类型声明 等同于 const String str1 = "hi world";
const str1 = "hi world";
}
- 不能修改一个 final 变量的值:
void main() {
//可以省略String这个类型声明 等同于 final String str = "hi world";
final str = "hi world";
// Error: a final variable can only be set once.
str = "hello world";
}
- 如果使用 const 修饰类中的变量,则必须加上 static 关键字,即 static const。在声明const变量时可以直接为其赋值,也可以使用其它的 const 变量为其赋值:
void main() {
const a = 1;
const double b = 1.013 * a;
}
- const 关键字不仅仅可以用来定义常量,还可以用来创建 常量值,该常量值可以赋予给任何变量。
var foo = const [];
const baz = [];
上面的代码,可以将构造函数声明为const的,这种类型的构造函数创建的对象是不可改变的。
- 没有使用final或const修饰的变量的值是可以被更改的,即使这些变量之前引用过const的值
void main() {
var foo = const [];
foo=[1,2];
}
注意:
- 实例变量可以是 final 的但不可以是 const。
- 尽管final对象不能被修改,但它的字段可以被更改。相比之下,const对象及其字段不能被更改:它们是不可变的。
空安全(null-safety)
Dart 引入空安全后,则定义变量时我们可以指定变量是可空还是不可空。
int i = 8; //默认为不可空,必须在定义时初始化。
int? j; // 定义为可空类型,对于可空变量,我们在使用前必须判空。
// 如果我们预期变量不能为空,但在定义时不能确定其初始值,则可以加上late关键字,
// 表示会稍后初始化,但是在正式使用它之前必须得保证初始化过了,否则会报错
late int k;
k=9;
如果一个变量我们定义为可空类型,在某些情况下即使我们给它赋值过了,但是预处理器仍然有可能识别不出,这时我们就要显式(通过在变量后面加一个”!“符号)告诉预处理器它已经不是null了。
class Test{
int? i;
Function? fun;
say(){
if(i!=null) {
print(i! * 8); //因为已经判过空,所以能走到这 i 必不为null,如果没有显式申明,则 IDE 会报错
}
if(fun!=null){
fun!(); // 同上
}
}
}
如果函数变量可空时,调用的时候可以用语法糖:
fun?.call() // fun 不为空时则会被调用
内置类型
num(数字类型)
num是数字类型的父类,它有2个子类型:int和double。
- int:整数值;长度不超过 64 位。
- double :64 位的双精度浮点数字。
void main() {
var one = int.parse('1');
var onePointMore=double.parse('1.2');
var oneStr=1.toString();
var oneMoreStr=1.2.toString();
var twoStr=1.321.toStringAsFixed(2); // 输出字符串1.32
}
String(字符串类型)
- 字符串包含了 UTF-16编码的字符序列。可以使用单引号或者双引号来创建字符串:
void main() {
var str0='I am a String'
'hello world';
var str="I am a String"+"hello world";
}
可以使用 + 运算符或并列放置多个字符串来连接字符串。
- 使用三个单引号或者三个双引号也能创建多行字符串:
void main() {
var s1 = '''
You can create
multi-line strings like this one.
''';
var s2 = """This is also a
multi-line string.""";
}
- 在字符串前加上 r 作为前缀创建 “raw” 字符串(即不会被做任何处理(比如转义)的字符串):
var s = r'在 raw 字符串中,转义字符串 \n 会直接输出 “\n” 而不是转义为换行。';
bool(布尔类型)
使用 bool 关键字表示布尔类型,布尔类型只有两个对象 true 和 false,两者都是编译时常量。
var fullName = '';
assert(fullName.isEmpty);
List(数组)
在 Dart 中数组由 List 对象表示。
void main() {
var list = [1, 2, 3];
print('list的集合length:${list.length}');// length:3
// 使用扩展操作符(...)将一个 List 中的所有元素插入到另一个 List 中
var list1=[0,...list];
print('list1的集合length:${list1.length}');// length:4
// 使用空感知扩展操作符(...?),
// 适用于扩展操作符右边可能为 null,来避免产生异常
var list3=null;
var list4=[0,...?list3];
print('list1的集合length:${list4.length}');// length:1
}
- 使用 集合中的 if 来添加元素:
void main() {
bool isAdd = true;
var list = ['1', '2', ' 3',if(isAdd)'4'];
print(list.toString()); // [1, 2, 3, 4]
}
- 使用集合中的for将列表中的元素修改后添加到另一个列表:
void main() {
bool isAdd = true;
var list = ['1', '2', ' 3'];
var list1 = ['0', for (var i in list) i];
print(list1.toString()); // [0, 1, 2, 3]
}
Set(集合)
在 Dart 中,set 是一组特定元素的无序集合。
- 创建Set 集合方式
void main() {
// 创建Set 方式1
var setString=<String>{};
// 创建Set 方式2
Set<String> setString={};
// 创建Set 方式3
var setString={'a','b'};
}
- 基本方法
void main() {
var setString = <String>{};
var anOther = {'a', 'b'};
setString.add('c');
setString.addAll(anOther);
var length=setString.length;
}
Map(集合)
Map 是用来关联keys和values的对象。其中键和值都可以是任何类型的对象。每个键只能出现一次,但是值可以重复出现多次。
void main() {
// 使用 Map 字面量创建 Map
var strMaps = {1: 'a', 2: 'b', 3: 'c'};
// 使用构造器创建Map 等同于 strMaps=new Map<int,String>();
var strMaps = Map<int, String>();
// 添加元素
strMaps[1] = 'a';
strMaps[2] = 'b';
strMaps[3] = 'c';
assert(strMaps.length==3);
}