变量声明
变量声明可以用以下方式:
var str='hello dart';
var num=123;
// 字符串类型
String str='hello dart';
// 数字类型
int num=123;
使用 var 可以自动推断类型,也可以像 Java 一样手动写上类型String
数据类型
数字
num类型,是数字类型的父类型,有两个子类 int 和 double
// 1.整数类型int
int age = 18;
int hexAge = 0x12;
print(age);
print(hexAge);
// 2.浮点类型double
double height = 1.88;
print(height);
// num是int和double的父类型
num age = 18;
字符串
Dart字符串是UTF-16编码单元的序列。您可以使用单引号或双引号创建一个字符串:
//1.定义字符串的方式
var s1 = 'Hello World';
var s2 = "Hello Dart";
var s3 = 'Hello\'Fullter';
var s4 = "Hello'Fullter";
可以使用三个单引号或者双引号表示多行字符串:
// 2.表示多行字符串的方式
var messagel = '''
哈哈哈
呵呵呵
咪嘿嘿''';
字符串拼接
在Dart中,可以使用多种方式拼接字符串
- 使用
+ - 使用字符串插值(使用
${expression}) - 使用
StringBuffer类进行高效的拼接(当需要拼接大量字符串时)
String string1 = 'Hello, ';
String string2 = 'World!';
String result = string1 + string2; // 结果为 'Hello, World!'
String name = 'Dart';
String result = 'Hello, ${name}!'; // 结果为 'Hello, Dart!'
StringBuffer buffer = new StringBuffer();
buffer.write('Hello, ');
buffer.write('World!');
String result = buffer.toString(); // 结果为 'Hello, World!'
数字和字符串互转
// 字符串和数字转化
//1.字符串转数字
var one = int.parse('111');
var two = double.parse('12.22');
print('S(one) S(one.runtimeType}'); // 111 int
print('$(two) $(two.runtimeType}'); // 12.22 double
// 2.数字转字符申
var num1 = 123;
var num2 = 123.456;
var num1Str = num1.toString();
var num2Str = num2.toString();
var num2StrD = num2.toStringAsFixed(2); // 保留两位小数
print('$(num1Str) $(num1Str.runtimeType)'); // 123 String
print('$(num2Str) $(num2Str.runtimeType)'); // 123.456 String
print('$(num2StrD) $(num2StrD.runtimeType)'); // 123.46 String
布尔
布尔类型中,Dart提供了一个 bool 的类型取值为 true 和 false
var isFlag - true;
print('$(isFlag) $(isFlag.runtimeType)');
dart中无法像javascript中进行非空判断,因为dart是强类型,不会自动进行类型判断if(exper)中exper只能为true or false 而不能是''、null、0等
集合类型
对于集合类型,Dart 则内置了最常用的三种: List / set / Map
其中,list 可以这样来定义:
list的声明方式
var arr = <String>['0', '1', '2', '3']; // 定义数组类型
var arr1 = [0, 1, 2, 3, 4]; //自动推断
List arr5 = <String>['0', '1', '2', '3'];// 使用类型的方式定义list
-
使用 const 关键字创建编译时变量,不能修改、增加
var arr2 = const [1, 2, 3, 4]; // 创建一个编译时的常量,不能修改、增加 arr2.add(5); // Cannot add to an unmodifiable list -
创建一个固定长度的集合
var arr3 = List.filled(2,'');// 创建一个固定长度的集合 var arr4 = List.filled<int>(2,0);// 创建一个固定长度的有类型的集合 -
扩展操作符对数组的操作
var list = [1, 2, 3]; var list2 = [0, ...list]; // 将 list 插入 list2 中 assert(list2.length == 4); -
空感知操作符对数组的操作,如果是 null 则可以避免异常
var list; var list2 = [0, ...?list]; assert(list2.length == 1); -
获取数组长度
var arr = <String>['0', '1', '2', '3']; arr.length -
判断是否为空
var arr = <String>['0', '1', '2', '3']; arr.isEmpty arr.isNotEmpty -
翻转数组
var arr = ['1', '2']; var newArr = arr.reversed.toList(); print(newArr); -
在 List 中可以使用 if 或 for
var nav = ['Home', 'Furniture', 'Plants', if (true) 'Outlet']; var listOfInts = [1, 2, 3]; var listOfStrings = ['#0', for (var i in listOfInts) '#$i']; print(listOfStrings); // [#0, #1, #2, #3]
Set 和 List 最大的两个不同就是: set 是无序的,并且元素是不重复的
// Set的定义
// 1.使用类型推导定义
var lettersSet = {'a', 'b', 'c', 'd'};
print('$lettersSet ${lettersSet.runtimeType}');
// 2.明确指定类型
Set<int> numbersSet = {1, 2, 3, 4};
print("$numbersSet ${numbersSet.runtimeType}");
//增加元素
var sets = <Object>{};
sets.add('1');
sets.addAll([1, 2, 3]);
print(sets);
//长度
print(sets.length);
//展开运算符
final sets = {'fluorine', 'chlorine'};
var maybeNull;
final a = <String>{'hello', ...sets};
final b = <String>{'hello', ...?maybeNull};
print(a);
print(b);
最后,Map 是我们常说的字典类型
const a = [1, 2, 3];
var map = {a: '123'}; // map 当 js 的map 用,key 不用写成[key]
var map1 = <String,String>{'a': '123'}; // map 当js 的 object用,key需要加引号
var map2 = Map(); // 创建自由类型的 map,可以加 new
var map3 = Map<int, String>(); // 创建 map 时定义类型
map3[1] = '1'; // 给 map 赋值
print(map);
print(map1);
print(map.containsKey(a)); // js的 map.has 方法判断是否有这个 key
map1['asdads'] //null; //不存在的键值对返回null
//增加键值对
var map = {};
map['age'] = 20;
map.addAll({"name": 'qiuyanxi', 1: 2});
print(map);
//展开运算符
var map = {'name': "qiuyanxi"};
Map? maybeNull;
var newMap = {...map};
var newMap2 = {...?maybeNull};
const和final
常量可以用 final 和 const 修饰符来声明,这两个关键字可以替代 var或者加在类型前面。
final
final name='some name';
const age=20;
const int age = 123;
final List list = [];
final包含了const的功能,区别在于:
- final 可以一开始不赋值,如果赋值了则只赋值一次。const 一开始就需要赋值
- const 必须给一个明确的编译常量值(即编译期间就确定的值)
- final 可以通过计算/函数获取一个值(即运行期间确定的值)
- final 不仅有 const 编译时的常量的特性,而且是惰性初始化,即在运行时第一次使用前才初始化
举个例子
// 报错了 const一开始就需要赋值 The constant 'a' must be initialized.
const a;
// 报错了 Const variables must be initialized with a constant value.
const a = new DateTime.now();
final b;
b = new DateTime.now(); // 不会报错
const 变量是编译时常量。如果使用 const 修饰类中的变量,则必须加上 static 关键字,即 static const。
const
在声明 const 变量时可以直接为其赋值,也可以使用其它的 const 变量为其赋值。
const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere
const 关键字不仅仅用来定义常量,还可以用来创建常量值,该常量值可以赋予给任何变量。也可以将构造函数声明为 const,这种类型的构造函数创建的对象是不可改变的。
var foo = const [];
final bar = const [];
const baz = []; // 相当于`const []`
使用初始化表达式为常量赋值就可以省略掉关键字 const,比如常量 bar 的赋值就省略掉了 const。
使用 const 变量还能够创建一个类似单例的对象,比如下面的语法,能够创建一个相同的对象
class Person {
final String name;
const Person(this.name);
}
void main(List<String> args) {
const p1 = const Person('myname');
const p2 = Person('myname'); // const 可以省略
print(identical(p1, p2));// 这两个对象是相等的
}
Objecr和dynamic
所有变量引用的都是对象,每个对象都是一个类的实例。数字、函数以及nulll都是对象。除了null外(如果开启了空安全),所有类都继承于Object类。
Object 是所有类的基类,相当于一个可以兼容所有类型的超级类型。dynamic 就是一个动态类,类似 TypeScript 的 any。
在下面代码中,如果用 Object 类声明会过不了编译。
Object a = 'String';
a.subString(1); //❌The method 'subString' isn't defined for the type 'Object'
换成dynamic就表示这是动态类型,可以绕过编译检查。
dynamic a = 'String';
a.substring(1);