变量
变量声明
1. 通过var
-
var name='Bob'
-
变量存储的是对象的引用
-
变量存储的是对象的引用,这里的变量
name
存储了一个String
类型的引用,Bob
则hi这个String
类型的引用的值 -
var声明变量后如果没有初始值,可以变成任何类型
-
var a; a="name"; a=123; a=true; //这样没有错误编译时根据值来推断类型
-
如果有初始值类型将被锁定,不可改变数据类型
-
var name="Bob"; name=1000 // 这样是错误的
-
-
name变量的类型被推断为String(Dart支持类型推断)
2.指定类型
可以通过指定类型的方式来改变变量类型,如果对象不确定单个类型可以指定为object或者dynamic
object
-
动态任意类型类型可变, 编译阶段检查
-
Object object = "hello world"; print(object.runtimeType); //String print(object); //hello world object = 1; print(object.runtimeType); //int 说明类型是可变的 print(object); //1 //object.foo();静态检查会运行报错会报错 object.foo();
-
dynamic
-
动态任意类型,编译阶段不检查运行阶段检查
-
dynamic mic = "hello world"; //编译时不会揣测数据类型,但是运行时会推断 print(mic.runtimeType); //String print(mic); //hello world //但是这样的坏处就是会让dart的语法检查失效,所以有可能会造成混乱而不报错 //所以不要直接使用dynamic mic.foo(); //通过它定义的变量会关闭类型检查,这段代码静态类型检查不会报错,但是运行时会crash,因为mic并没有foo()方法, // 所以建议大家在编程时不要直接使用dynamic mic = 1; print(mic.runtimeType); //int 说明类型是可变的 print(mic); //1
-
3.显式声明可以推断出的类型
-
String name='Bob';
4 . 通过final const 声明不可变变量 下面有介绍
final ,const(常量)
使用过程中从来不会被修改的变量(可以称为常量),
可以使用final或const
Fianl变量的值只能被设置一次;final定义的常量可以用变量来初始化
Const变量在编译阶段就已经固定(Const 时隐式的final类型最高级 final 变量)最高级 final 变量或类变量在第一次使用时被初始化。(编译时常量)
实例变量可以是
final
类型但不能是const
类型。 必须在构造函数体执行之前初始化 final 实例变量 —— 在变量声明中,参数构造函数中或构造函数的初始化列表中进行初始化
var a; //final定义的常量可以用变量来初始化 final b=a;// 可以 final time = new DateTime.now(); //Ok // const定义的是编译时常量,只能用编译时常量来初始化 const c=a;// error const time = new DateTime.now(); //Error,new DateTime.now()不是const常量
Const 关键字不仅可以用于声明常量变量。 还可以用来创建常量值,以及声明创建常量值的构造函数。 任何变量都可以拥有常量值。
来点简单的描述
final const 用来修饰不可变变量
- 啥不可变变量 就是常量。。
声明必须赋值
区别
final 可以赋值为变量 在运行前确定其值即可
const 赋值必须为编译时常量,因为其编译时会检测
顾名思义编译时常量只有编译前可以改变值 编译时无法改变
比如将其作为参数传递 参考后面的 可选参数示例
示例
//可传递List map 作为可选参数 //const 表示编译时常量 故名思意 只有编译前可以改变值 编译后无法改变 void doStuff( {List<int> list = const [1, 2, 3], Map<String, String> gifts = const { 'first': 'paper', 'secend': 'cotton', 'third': 'leather' }}) { print('list: $list'); print('gifts:$gifts'); } //调用 注意看 const list 是不是发生了改变 默认值变了 List<int> list = [4, 5, 6]; Map<String, String> map = { 'one': 'param1', 'two': 'param2', 'three': 'param3' }; doStuff(list: list, gifts: map);
默认值
未初始化的变量默认值是
null
。即使变量是数字 类型默认值也是 null,因为在 Dart 中一切都是对象,数字类型 也不例外。
静态变量
通过static 修饰 类级别变量 全局类名调用访问
类型
Number
Dart 语言的 Number 有两种类型:
int
-
var x = 1;
double
-
var y = 1.1; var exponents = 1.42e5; //从 Dart 2.1 开始,必要的时候 int 字面量会自动转换成 double 类型。 double z = 1; // 相当于 double z = 1.0.
类型转换
-
// 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');
String
Dart 字符串是一组 UTF-16 单元序列。
-
字符串通过单引号或者双引号创建。
-
String name="Bob"; String name='Bob';
-
-
单引号或者双引号里嵌套使用引号
-
String msg="hello 'Bob' ,How are you"; String msg2 = 'Hello "Bob" ,How are you'; print(msg); print(msg2); //Hello 'Bob' ,How are you //Hello 'Bob' ,How are you
-
-
字符串可以通过
${
expression
}
的方式内嵌表达式。 如果表达式是一个标识符,则 {} 可以省略。-
String name = "Bob"; String msg = "Hello '$name' ,How are you"; String msg2 = 'Hello "${name.toUpperCase()}" ,How are you'; print(msg); print(msg2); //Hello 'Bob' ,How are you //Hello "BOB" ,How are you
-
-
使用连续三个单引号或者三个双引号实现多行字符串对象的创建:
-
var msg3=''' hello Bob How are you '''; print(msg3); //hello Bob 保留定义字符串格式 // How are you
-
-
使用r 前缀创建原始字符串
-
原始(raw)字符串,在原始(raw)字符串中,字符表示的就是其本身,转义字符会失去意义。
\n
不是换行,而是普通的\
和n
字符。 -
var s = r"In a raw string, even \n isn't special."; print(s); //In a raw string, even \n isn't special.
-
Boolean
Dart 使用
bool
类型表示布尔值。只有bool 类型的值是true 才被认为是true。 Dart 只有字面量true
andfalse
是布尔类型, 这两个对象都是编译时常量。Dart 的类型安全意味着不能使用
if (*nonbooleanValue*)
或者assert (*nonbooleanValue*)
。 而是应该像下面这样,明确的进行值检查:
// 检查是否为空字符串 var fullName = ''; assert(fullName.isEmpty); if (fullName.isEmpty) { print('fullName null'); } // 检查0 var hitPoints = 0; assert(hitPoints <= 0); // 检查是否为null var unicorn; assert(unicorn == null); // 检查是否为NaN var iMeantToDoThis = 0 / 0; assert(iMeantToDoThis.isNaN);
List
-
Array 就是 List 对象, 通常称之为 List 。
-
注意事项
-
可以直接打印list包括list的元素,list也是一个对象。但是java必须遍历才能打印list,直接打印是地址值
-
和java一样list里面的元素必须保持类型一致,不一致就会报错。
-
和java一样list的下标从0开始。
-
List list = [10, 7, 23]; // 输出[10, 7, 23] print(list); // 类型推断为int类型的list 存放其他类型将出错 //list.add("1")//error
-
-
如果集合里面有多个相同的元素“X”, 只会删除集合中第一个该元素
-
非元素累固定型List 可以存放多种类型格式数据
-
List listMore = new List(); listMore.add('1'); //String listMore.add(1); //int listMore.add(1.111); //double listMore.add(true); //boolean print(listMore);
-
-
使用List的构造函数,也可以添加int参数
-
List testList = new List(10); //长度为10的list集合 表示List固定长度,不能进行添加 删除操作 添加数据会提示Exception
-
-
-
创建list
-
//创建一个int类型的list 固定数据类型只能存放固定类型数据 List intList = new List<int>(); //非元素累固定型List 可以存放多种类型格式数据 List listMore = new List(); listMore.add('1'); //String listMore.add(1); //int //长度为10的list集合 List testList = new List(10);
-
-
常用函数
-
var fruits = new List(); // 添加元素 fruits.add('apples'); // 添加多个元素 fruits.addAll(['oranges', 'bananas']); List subFruits = ['apples', 'oranges', 'banans']; // 添加多个元素 fruits.addAll(subFruits); // 输出: [apples, oranges, bananas, apples, oranges, banans] print(fruits); // 获取List的长度 print(fruits.length); // 获取第一个元素 print(fruits.first); // 获取元素最后一个元素 print(fruits.last); // 利用索引获取元素 print(fruits[0]); // 查找某个元素的索引号 print(fruits.indexOf('apples')); // 删除指定位置的元素,返回删除的元素 print(fruits.removeAt(0)); // 删除指定元素,成功返回true,失败返回false // 如果集合里面有多个“apples”, 只会删除集合中第一个改元素 fruits.remove('apples'); // 删除最后一个元素,返回删除的元素 fruits.removeLast(); // 删除指定范围(索引)元素,含头不含尾 // fruits.removeRange(start,end); // 删除指定条件的元素(这里是元素长度大于6) fruits.removeWhere((item) => item.length > 6); // 删除所有的元素 fruits.clear(); // 可以使用 sort() 函数来排序, 但是由于我们使用定义的数组类型不一样,就不能使用 var sortList = [1, 2, 4, 5, 3, 6]; // 根据语法提示: List.sort([(int, int) → int compare]) → void sortList.sort((a, b) => a.compareTo(b)); print(sortList); // 输出[1, 2, 3, 4, 5, 6] sortList.sort((a, b) => b.compareTo(a)); print(sortList); //[6, 5, 4, 3, 2, 1]
-
Set
-
元素唯一且无序的集合
-
实例
-
var names =new Set<String>(); names.addAll(['dart', 'c#', 'j#', 'e#']);
-
-
创建
-
var names =new Set<String>(); names.addAll(['dart', 'c#', 'j#', 'e#']); Set<String> name = {} as Set<String>; // 这样也是可以的。 Set<String> n=new Set<String>(); Set ns=new Set(); //Set ns=new Set(2);//不支持指定长度 //var nams = {}; // 这样会创建一个 Map ,而不是 Set 。
-
-
常用函数
-
使用
add()
或addAll()
为已有的 Set 添加元素:-
var elements = <String>{}; elements.add('fluorine'); elements.addAll(halogens);
-
-
使用
.length
来获取 Set 中元素的个数:-
var elements = <String>{}; elements.add('fluorine'); elements.addAll(halogens); assert(elements.length == 5);
-
-
在 Set 字面量前增加
const
,来创建一个编译时 Set 常量:-
final constantSet = const { 'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine', }; // constantSet.add('helium'); // Uncommenting this causes an error
-
-
Map
-
Map 是用来关联 keys 和 values 的对象。 keys 和 values 可以是任何类型的对象。在一个 Map 对象中一个 key 只能出现一次。 但是 value 可以出现多次。
-
创建map
-
Map companys = {}; Map company=new Map(); Map ma=Map();// 为什么不用new 因为new 在dart2.0 可选 // 指定键值对类型 var aMap = new Map<int, String>(); Map<int,String> aMap = new Map<int, String>();
-
-
数据添加
-
//初始化里面写key和value,每组键值对中间用逗号隔开。 Map companys = {'Alibaba': '阿里巴巴', 'Tencent': '腾讯', 'baidu': '百度'}; // 通过key-value添加 companys["accenture"]="埃森哲"; // 通过整体合并另一个map 泛型要一致 var fruit = new Map(); fruit["first"] = "apple"; fruit.addAll(companys); //addEntries() 合并两个map 如果key有重复,被合并的map的value覆盖前者 // 形势一 通过Map Map<String,int> map26 = {"a":1,"b":2,"c":3}; Map<String,int> map27 = {"a":1,"b":4,"d":3,"e":5}; map26.addEntries(map27.entries); //print(map26);//{a: 1, b: 4, c: 3, d: 3, e: 5} // 形式二 通过list<MapEntrie> List<MapEntry<String, String>> list = new List(); list.add(MapEntry("keyadd", "valueAdd")); fruit.addEntries(list.reversed); //通过Iterable增加数据
-
-
取出数据 通过key
-
var gifts = {'first': 'partridge'}; assert(gifts['first'] == 'partridge'); //若map中不存在要查找的key map返回null var gifts = {'first': 'partridge'}; assert(gifts['fifth'] == null);
-
-
通过.length函数获取当前map 的键值对个数
-
var m={'key1':'key','key1':'key1}; assert(m.length==2);
-
-
创建map运行时常量 要通过const
-
final constmap=const{'key1':'value1', 'key2':'value2', 'key3':'value3',}; constmap['key1']='hello';//该行代码会报错 因为const 标明的变量值不可修改
-
Rune
谨慎使用 list 方式操作 Rune 。 这种方法很容易引发崩溃, 具体原因取决于特定的语言,字符集和操作。
在 Dart 中, Rune 用来表示字符串中的 UTF-32 编码字符。
Unicode 定义了一个全球的书写系统编码, 系统中使用的所有字母,数字和符号都对应唯一的数值编码。 由于 Dart 字符串是一系列 UTF-16 编码单元, 因此要在字符串中表示32位 Unicode 值需要特殊语法支持。
表示 Unicode 编码的常用方法是,
\uXXXX
, 这里 XXXX 是一个4位的16进制数。 例如,心形符号 (♥) 是\u2665
。 对于特殊的非 4 个数值的情况, 把编码值放到大括号中即可。 例如,emoji 的笑脸 是\u{1f600}
。String 类有一些属性可以获得 rune 数据。 属性
codeUnitAt
和codeUnit
返回16位编码数据。 属性runes
获取字符串中的 Rune 。var clapping = '\u{1f44f}'; print(clapping); print(clapping.codeUnits); print(clapping.runes.toList()); //使用String. fromCharCodes显示字符图形 Runes input = new Runes( '\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}'); print(new String.fromCharCodes(input)); // 输出 // 👏 // [55357, 56399] // [128079] // ♥ 😅 😎 👻 🖖 👍
Symbol
一个 Symbol 对象表示 Dart 程序中声明的运算符或者标识符。 你也许永远都不需要使用 Symbol ,但要按名称引用标识符的 API 时, Symbol 就非常有用了。 因为代码压缩后会改变标识符的名称,但不会改变标识符的符号。 通过字面量 Symbol ,也就是标识符前面添加一个
#
号,来获取标识符的 Symbol 。#radix #bar