作者:opLW

目录

1.变量
2.常量
3.内建类型
4.集合
5.运算符


1.变量
  • 1.1 变量类型 Dart中没有基本数据类型的说法,任何变量都是类的实例并且这些类都继承自Object
  • 1.2 变量的默认值 Dart中所有变量默认值都为null,不像Java中基本类型有其对应的默认值。
  • 1.3 变量的声明
  • var Dart中除了可以像Java一样明确声明变量类型外,还引入var标识符来声明变量,被var修饰的变量的类型由系统根据变量实际值进行推断。
String name = 'Bob';
var name = 'Bob';
  • dynamicdynamic标识符修饰变量时,相当于告诉编译器开发者自己能保证代码正确,不用编译器对这个变量的进行检查。如下代码在编译时不会出现警告,而运行时会抛出异常,因为A类没有foo这个方法。
void main() {
   dynamic a = A();
   a.foo();
 }
 class A {}
  • 使用dynamic标识符时,开发者需要自行保证正确。
    注意 Dart中的集合类,如果不特别声明泛型的类型,那么默认使用dynamic代替。
  • 1.4 变量的实例化
  • new关键字 在实例化对象时,new关键字变为可选,即可以省略new关键字


2.常量
  • 2.1 final 与Java一样,final修饰的变量代表其只能被设置一次。因为Dart中没有基本变量,所以可以认为被final修饰的变量,其不能引用其他对象。
  • 由于Dart能进行类型推断,所以可以声明变量时可以省略类型。
final String nickname = 'Bobby';
final name = 'Bob'; // Without a type annotation
name = 'Alice'; // Error: 一个 final 变量只能被设置一次。
  • 2.2 编译期常量:const
  • const相对于final的要求更高,除了被修饰变量不能引用其他对象外,const修饰的变量为编译期常量,即在编译器编译代码时就确定变量的值。
  • 如果const修饰的常量属于类级别的,那么应该用static const修饰,类似于Javapublic static final修饰的变量。
void main() {
  print(A.str);
  
  const str1 = 'I am a Char too';
  print(str1);
}
class A {
  static const str = 'I am a Char';
}
  • 在字符串中含有算术表达式或变量时,只要变量是编译时常量, 那么算术表达式的结果也是编译时常量;
void main() {
  print(A.number2);
}     
class A {
  static const c = 1;
  static const d = 2;
  static const number2 = 'I am ${c + d}';
}
  • const除了用于声明编译期常量外,也可用于创建编译期常量,这需要该类拥有常量构造函数
const a = [1,2,3]; // const用于声明变量
//a = [2,3,4];  再次对a赋值。发生错误,因为a是一个const类型的变量

var b = const [3, 4, 5]; // 创建编译器常量
//b[0] = 10;  发生错误,因为此时的b指向一个常量,不能对其内容进行修改
b = [4, 5, 6]; // 正常,因为b是一个var类型变量
b[0] = 10; //正常,因为此时b已经指向另一个不为const的变量了

var a = const[1,2,3];
var b = const[1,2,3];
if (identical(a,b)) {
   print(true);
}
// 输出true,因为a和b都指向同一个编译期常量


3.内建类型 (Dart自带的类型)
  • 3.1 数字类型 Dart中没有float类型,只有doubleint
  • int取值范围在Dart VM上为 -263 到263-1
  • 只要值中含有小数点那么就认为是double类型
  • 从Dart 2.1开始,必要的时候int字面量会自动转换成 double 类型。
double z = 1; // 相当于 double z = 1.0.
  • 3.2 字符串
  • Dart中字符串可用单引号或者双引号进行声明。
String str = 'The code can\'t be set'
String str = "The code can't be set"
  1. 如果在用单引号包括的字符串中使用单引号,则需要进行转义。
  2. 如果在用双引号包括的字符串中使用双引号,同样需要进行转义。
  3. 但双引号包括的字符串中使用单引号则不需要转义。
  • 使用连续三个单引号或者三个双引号实现多行字符串对象的创建。
var s1 = '''
You can create
multi-line strings like this one.
''';

var s2 = """This is also a
multi-line string.""";
  • 字符串模板 字符串可以通过 ${expression} 的方式内嵌表达式。 如果表达式是一个标识符,则 {} 可以省略。
String str1 = "I am ${a + b}" 
String str2 = "I am $a"
  • 原始字符串 通过在字符串前面添加“r”字符,让字符串保持原生输出,即字符串内容是什么就输出什么。
void main() {
  int a = 1;
  int b = 2;
  final str1 = r"I am ${a + b} can\'t be 3";
  print(str1);
  // 输出:I am ${a + b} can\'t be 3
  
  final str2 = r'I am ${a + b} can\'t be 3';
  print(str2);
  // 错误,详细原因见下方
}
  • 注意:当原生字符串中含有单引号时,需要使用双引号包裹。否则由于转义字符被忽略,将导致\'中的单引号被误认为是字符串结束,引发错误。
  • 布尔值 Dart中使用bool声明布尔值,有truefalse两个值并且这两个值都为编译期常量。


4.集合
  • 4.1 List
var list = [1, 2, 3]; // 通过方括号创建
var length = list.length; // 获取list对象的length属性
list[1] = 2; // 通过list[i]访问或设置元素
  • 4.2 Map
// 通过键值对和中括号的形式创建Map
var gifts = {
 // Key: Value
 'first': 'partridge',
 'second': 'turtledoves',
 'fifth': 'golden rings'
}; // 系统自动推断为Map<String,String>类型

var nobleGases = {
 2: 'helium',
 10: 'neon',
 18: 'argon',
}; // 系统自动推断为Map<int,String>类型

var gifts = Map(); // 通过实例化Map类创建
gifts['first'] = 'partridge'; // 通过map[key]访问或设置元素
  • 4.3 Set
// Set是在Map的基础上进行扩展的,所以需要使用“<Type>”特别声明类型
var names = <String>{}; // 形式一
Set<String> names = {}; // 形式二

// 不特别声明类型则默认为Map类
var names = {}; // 这样会创建一个 Map ,而不是 Set 。
  • 4.4 Rune
  • 作用 Dart中String类使用UTF-16进行编码,但这种字符集能够表示的字符数量有限,所以Dart中使用Rune类来表示更多字符如emoji表情等。
  • 编码: 全世界存在各种各样的符号如‘a’、'我’及emoji表情,所以为了让计算机识别种类繁多的字符,需要用独一无二的二进制串标记这个字符。
  • 字符集: 编码的字符越多需要的位数越多,但是部分应用可能仅在某个国家使用,不需要使用到他国的字符,所以不需要对其他国家的字符进行编码。因此为了节省资源就出现了字符集。字符集仅对部分字符进行编码,不同的地区使用不同的字符集。
  • Rune 用来表示字符串中的 UTF-32 编码字符,使用如\uXXXX的形式,其中的XXXX代表4个16进制。如果还不够表示则用\u{大于4个X}共6位。
Runes input = new Runes(
 '\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d}');
 // 输出结果是:♥  😅  😎  👻  🖖  👍


5.运算符
  • 5.1 算术运算符 Dart中大部分运算符与Java类似,不同的是
  • / 在Dart中/求出的结果是double类型。
  • ~/ 在Dart中~/求出的结果int类型,对应Java中的/运算符。
  • 5.2 关系运算符
  • 判断两个变量是否指向同一对象 Java中使用==符号;Dart使用identical(Object a, Object b)方法,该方法属于dart:core包。
  • == Dart中使用==符号比较两个变量的是否相等,要想使用这个符号,需要在类中重写==运算符。
  • 5.3 类型运算符
  • is 判断一个变量是否属于一个类。如果变量为null或不属于该类则为false,否则返回true并在该作用域内将该变量智能的转化为该类的实例如:
if (emp is Person) {
  // emp已经默认转为Person类的实例
  emp.firstName = 'Bob';
}
  • !is 判断一个变量是否不属于一个类,不属于则为true
  • as 将一个变量强行转为该类,如果变量为null或不属于该类型则抛出异常
(emp as Person).firstName = 'Bob';
  • 5.4 赋值运算符
  • ??= Dart中除了常规的=赋值运算符外,还有??=运算符,该运算符只有在左边变量为null时,才会将右边的值赋给左边变量。
  • 复合赋值运算符 如Java中的+=赋值运算符在Dart中同样适用
  • 5.5 逻辑运算符&&||等基本与Java中一样
  • 5.6 按位和位移运算符&(与运算符)|(或运算符)等基本与Java中一样
  • 5.7 条件表达式 Dart中除了有三目条件表达式exper ? trueExper : falseExper外,还有
  • exper1 ?? exper2 exper1不为null则执行并返回exper1exper1null则执行并返回exper2
  • 5.8 级联运算符 Dart中的级联运算符有点类似Kotlin中的作用域函数
  • 可以对同一个对像进行一系列的操作如调用函数、 访问对象的字段属性,每句代码执行后的返回值会被忽略。
querySelector('#confirm') // 获取对象。
  ..text = 'Confirm' // 调用成员变量。
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'));
  • 级联的代码可以嵌套
final addressBook = (AddressBookBuilder()
..name = 'jenny'
..email = 'jenny@example.com'
..phone = (PhoneNumberBuilder()
      ..number = '415-555-0100'
      ..label = 'home')
    .build())
 .build();
  • 切记级联的符号是两个点不是一个点。错误示范如下:
var sb = StringBuffer();
sb.write('foo') // 少写了一个点,导致错误
  ..write('bar'); // Error: 'void' 没有定义 'write' 函数。
  • 5.9 其他运算符
  • ?. Dart与Kotlin类似有一个空安全访问符号。如例子foo?.bar,如果foo不为null才会访问bar属性,如果为null则不访问,以此来避免NPE。

万水千山总是情,麻烦手下别留情。
如若讲得有不妥,文末留言告知我,
如若觉得还可以,收藏点赞要一起。