跨平台的意思就是写一套代码,可以用于做移动端的app,网页,桌面应用,以及智能手表,车载系统等智能设备上的应用。(要学Flutter的话必须首先得学会Dart)
一、 Dart 开发工具
在Vs code中配置Dart
找到vscod插件安装dart
-
找到vscode插件安装code runner (code Runner) 可以运行我们的dart文件
实例:鼠标右键选择run code 运行,vscode的控制台输出就会打印出'你好 dart'main() { print('你好 dart'); }
每个应用都有一个顶层的
main()
函数来作为运行入口。没有指定返回类型的方法的返回类型会推导为void
。你可以使用顶层函数print()
来将一段文本输出显示到控制台:void main() { print('Hello, World!'); }
二、定义变量
1.1 明确声明(Explicit)
明确声明变量的方式,格式如下:
变量类型 变量名称 = 赋值;
实例代码
String name = "Maybe";
print(name);
int age = 18;
print(age);
double height = 24.5;
print(height);
// print("$name,$age,$height");
print("一个人${name}${age}${height}");
注意事项:定义的变量可以修改值,但是不能赋值其他的类型
name = 11; //error 定义的变量可以重新赋值,但是不能赋值其他类型
1.2 类型推导(Type Inference)
类型推导申明变量的方式,格式如下:
var/dynamic/const/final 变量名 = 赋值;
在Dart语法中,没有初始化的变量自动获取一个默认值为NUll,一切皆对象,对象的默认值为Null
var thisNull;
print("$thisNull,thisNull的类型 ${thisNull.runtimeType}");
输出:null,thisNull的类型 Null
1.2.1 var的使用
var的使用实例
- runtimeType用于获取变量当前的类型
var type1 = 1; //申明变量
print("当前type1的类型 ${type1.runtimeType}"); /*用于获取变量当前的类型*/
var 的错误用法
type1 = "2"; //不可以将一个String赋值给一个int类型
1.2.2 dynamic的使用
dynamic 在 dart 中自由度最大。 让 dart 具有充分的灵活性。如果所有变量都用 dynamic,相当于完全放弃类型检查。
在开发中,通常情况下不是用dynamic来申明变量
dynamic type2;
print("改变前type2的变量类型 ${type2.runtimeType}");
type2 = 1;
print("改变后type2的变量类型 ${type2.runtimeType}");
输出:改变前type2的变量类型 Null
改变后type2的变量类型 int
在这里,使用dynamic申明的变量,重新赋值之后,会改变变量的类型
1.2.3 final&const的使用
final、 const 都是用于定义常量的,也就是定义之后不可以做修改
const type3 = "3"; //申明常量
final type4 = "type4";//申明常量
type3 = "4"; //错误
type4 = "type3"; //错误
在这里会报错
Error: Can't assign to the const variable 'type3'. 不能赋值给type3
Error: Can't assign to the final variable 'type4'. 不能赋值给type4
final 和 const有什么区别呢
- const在赋值时,赋值的内容必须是在编译期间就确定的,也就是写死的
- final在赋值时,可以动态获取,比如赋值一个函数
String getName() {
return "Maybe";
}
const getName1 = getName(); //在这里会报错,
final getName2 = getName();
- final 和 const 一旦被赋值,有确定的结果,就不会被再次赋值
class Person{
const Person();
}
final a = const Person();
final b = const Person();
print(identical(a,b)); //true
final a = Person();
final b = Person();
print(identical(a,b)); //flase
- const放在赋值语句的右边,可以共享对象,提高性能
class Person{
const Person();
}
final a = const Person();
final b = const Person();
print(identical(a,b)); //true
final a = Person();
final b = Person();
print(identical(a,b)); //flase
三、 数字类型
对于数值来说,我们也不用关心他是否有符号,以及数据的宽度和精度等问题。只需要整型用int,浮点型用double
就行
在Dart中的 int 和 double 可表示的范围并不是固定的,它取决于运行Dart的平台
main(List<String> args) {
/*整数类型 int*/
int age = 18;
int hexAge = 0x12;
print(age);
print(hexAge);
/*浮点型 double*/
double height = 1.88;
print(height);
//字符串转数字
var a = int.parse('1111');
var b = double.parse('22.22');
print('a的数据类型 ${a.runtimeType},a的值 $a' );//a的数据类型 int,a的值 1111
print('b的数据类型 ${b.runtimeType},b的值 $b' );//b的数据类型 double,b的值 22.22
//数字转字符串
var num1 = 123;
var num2 = 456.789;
var num3 = 1.234567890123;
var num4 = 2.456788656898;
var num1Str = num1.toString(); //num1Str的数据类型 String,num1Str的值 123
var num2Str = num2.toString(); //num2Str的数据类型 String,num2Str的值 456.789
var num2StrD = num2.toStringAsFixed(2); //保留2位小数,num2StrD的数据类型 String,num2StrD的值 456.79 我发现会四舍五入,这里不是简单的截取 如果 num2 = 456.781 num2StrD的值为 456.78
var num3Str = num3.toStringAsExponential(3); //指数
var num4Str = num4.toStringAsPrecision(4); //精度,也就是字符串的长度,不包含小数点,这里填4,输出 2.457
print('num1Str的数据类型 ${num1Str.runtimeType},num1Str的值 $num1Str');
print('num2Str的数据类型 ${num2Str.runtimeType},num2Str的值 $num2Str');
print('num2StrD的数据类型 ${num2StrD.runtimeType},num2StrD的值 $num2StrD');
print('num3Str的数据类型 ${num3Str.runtimeType},num3Str的值 $num3Str');
print('num4Str的数据类型 ${num4Str.runtimeType},num4Str的值 $num4Str');
}
3.2 布尔类型
布尔类型中,Dart提供了一个bool的类型,取值为true 和 flase
//布尔类型
var isFlag = true;
print('$isFlag ${isFlag.runtimeType}'); //true bool
注意:Dart中不能判断非0即为真,或者非空即真
Dart的类型安全性意味着你不能使用if(非booleanvalue)或者assert(非booleanValue)之类的代码
var message = 'Hello Dart';
if(message){
print('判断走了这里');
} //Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
3.3 字符串类型
Dart字符串是UTF-16编码单元的序列,你可以使用单引号或者双引号来创建一个字符串
var s1 = 'Hello Flutter';
var s2 = "Hello Flutter";
var s3 = 'Hello \'Flutter';
var s4 = "Hello ' Flutter";
var s5 = '''
111
222
333
444
'''; //这个表示多行字符串
在这里可以使用3个单引号来表示多行的字符串
字符串和其他变量或者表达式拼接时,使用${expression},如果表达式是一个标识符,那么{}可以省略.
print("s1 = $s1 s2 = $s2 s3 = $s3 s4 = $s4 s5 = ${s5}");
3.4 集合类型
3.4.1 集合类型的定义
对于集合类型,Dart内置了常用的三种: List /Set /Map
//List 定义
//1、使用类型推导定义
var list1 = ['a','b','c','d'];
print('$list1, ${list1.runtimeType}'); //[a, b, c, d], List<String>
//2、明确指定类型
List<int> list2 = [1,2,3,4];
print("$list2,${list2.runtimeType}"); //[1, 2, 3, 4],List<int>
3.4.1.2 set定义
Set定义类似List,Set与List不同的就是 Set是无序的,并且元素不重复
var set1 = {1,2,3,4};
print('$set1,${set1.runtimeType}');
Set<String> set2 = {'小黑','小白','小灰'};
print('$set2,${set2.runtimeType}');
输出:
{1, 2, 3, 4},_Set<int>
{小黑, 小白, 小灰},_Set<String>
在Set中如果元素相同,我认为是会直接无视后面的相同的元素,同时会警告: Two elements in a set literal shouldn't be equal. Change or remove the duplicate element.
3.4.1.3 Map定义
//Map 也就是字典类型,键值对集合
//使用类型推导定义
var map1 = {'name':'Maybe','age':'18'};
print('$map1,${map1.runtimeType}'); //{name: Maybe, age: 18},_InternalLinkedHashMap<String, String>
Map<String,Object> map2 = {'height':'188','weight':'140'};
print('$map2,${map2.runtimeType}');//{height: 188, weight: 140},_InternalLinkedHashMap<String, Object>
3.4.1 集合的常见操作
3.4.1.1 获取集合的长度
所有集合都支持获取其长度 length
print('list1的长度,${list1.length}');//list1的长度,4
print('set1的长度,${set1.length}'); //set1的长度,4
print('map1的长度,${map1.length}');//map1的长度,2
3.4.1.2 添加/删除/包含操作
对于List 而言,由于元素是有序的,他提供了一个删除指定索引位置上的元素方法
常见的List的一些操作
list1.add('f');
list2.add(5);
print('List增加 $list1,$list2'); //List增加 [a, b, c, d, f],[1, 2, 3, 4, 5]
//在这里会报错 list2 是一个int类型的,他无法加入到一个string的list里面
//list1.addAll(list2); //Error: The argument type 'List<int>' can't be assigned to the parameter type 'Iterable<String>'.
list1.addAll(list3);//点击addAll这个方法进入官方文档可以看到注解:1.将[iterable]的所有对象追加到该列表的末尾;2.根据[iterable]中的对象数量来扩展列表的长度 ; 3. 如果该列表是固定长度的,则抛出[UnsupportedError]
print('拼接后的List$list1');// +++++++[a, b, c, d, f, x, y, z]
list1.remove('a'); //list1 删除a 元素
print('List指定删除某个元素 $list1'); //List指定删除某个元素 [b, c, d, f, x, y, z]
//在这里可以看出 下标是从0 开始的
list1.removeAt(1); // list1 删除下标为1 的元素
print('List删除下标为1 的元素 $list1');//List删除下标为1 的元素 [b, d, f, x, y, z]
list1.removeLast(); // list 删除最后一个元素
print('List删除最后一个元素 $list1');//List删除最后一个元素 [b, d, f, x, y]
list1.removeRange(0, 3); //
print('List 删除 从 0 - 3 的元素 后得到的 $list1');
// list1.removeWhere((element) => false);
// list1.removeWhere((element) => 1);
list1.contains(1); //是否包含某个元素,
print('${list1.contains(1)}');//这里返回false,因为现有的list1 里面只有 x,y 所以返回flase
常见的 Map操作
- 由于是key/value形式的,且是无序的,所以任何操作,都是需要明确是基于key、value或者是key/value.