• dart、flutter学习记录


    1、Dart入口、打印、变量声明、变量命名规则

    • 入口函数是main()函数;
    • void 表示函数没有返回值;
    • 注释方式和js类似;
    • 变量:
      var或则其他具体类型格式定义;var方式会自动推断类型的。
      如果使用具体类型格式定义的变量,后面赋予的值类型必须是规定好的,不然会报错;
      dart里面有类型校验;
    • 常量:
      const: 值不变,一开始就需要赋值;
      final: 可以开始不赋值,只能赋值一次。如果是一个函数的值要赋给一个变量,就可以选择final,而不能用const.
      如:final date = new DateTime.now();
    • dart变量的命名规则:(与其他语言类似)
      1、变量名称必须由数字、字母、下划线和美元符号($)组成;
      2、注意:标识符开头不能是数字;
      3、标识符不能是保留字和关键字;
      4、变量的名字是区分大小写的。如age和Age是不同的变量;但一般不建议这么写;
      5、标识符(变量名称)一定要见名思义:变量名用名词;方法名用动词。

    2、数据类型

    常用数据类型:
    Number: int double
    String: String
    Booleans: bool
    List: 在dart中数组是列表对象,所以大多数人成为它是列表;
    Map: map是一个键值对相关的对象。键和值都可以是任意类型数据。

    注意:
    1、字符串:可以用一个单引号、一个双引号包裹;也可以用三个单引号或双引号包裹

    String str1 = ‘’‘this is name
    this is
    name’‘’
    即三个引号的时候会数据可以写多行数据;一个引号的就会只显示到一行上

    2、字符串拼接
    print(“$str1 $str2”) 或则。print(str1 + str2)

    3、double类型的值既可以是int,也可以是double浮点类型;反过来int类型的值不可以赋double类型的值。

    4、list 赋值、控制类型、添加数据

    var list1 = ['开心', true, 123]
    var list2 = <String>['ssdg', 'etwyrey', 'dsgdsgds']; // 指定类型
    var list3 = [];    list3.add('李四'); list3.add(20);
    var list4 = new List(); // 初始化一个数组,新版本废弃,老版本可以使用
    var list5 = List.filled(6, ''); list[1]= '历史'; // 定义一个固定长度的数据, 参数表示长度、填充值; 修改内容; 不能在用list5.add()增加数据了,因为长度已固定;所以也是没办法改变长度的 如list5.length = 0; 也是错误的表达式。
    var list5 = List<String>.filled(6, '');// 制定类型数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5、定义map的方式:(key必须加上引号)

    // 方式一:
    var p = {
    	'name': 'lisi',
    	'age': 30,
    	'work': ['农民','码农']
    };
    print(p['name']); // 获取name的值
    
    //方式二:
    var p2 = new Map();
    p2['name']='zhagnsan';
    p2['age']= 20;
    print(p2['name']);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    is 关键词判断类型

    var str = 'sagsg' // 后台返回的数据
    if(str is String){
    	print('是string类型');
    } else if(str is int){
    	print('是int类型');
    }else {
    	print('是其他类型');
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3、运算法、条件表达式、类型转换

    与其他语言类似:
    算术运算符:
    +

    /
    ~/(取整)
    % (取余)
    ++

    关系运算符:
    == != > < >= <=

    逻辑运算符
    ! && ||

    赋值运算符
    基本赋值运算符: = ??=
    复合赋值运算符: += -= *= /= %= ~/=

    例子:

    b ??= 23; // 表示如果b的值为空就把23赋值过去;如果不为空值不变。
    
    • 1

    条件运算符
    if else switch case. 三目运算符 ? : ??

    var b;
    var a = b ?? 23; // 如果b的值为空就把23赋值给a;如果不为空则把b的值赋值过去。
    
    • 1
    • 2

    类型转换
    Number ----->转 String : toString()
    String ---------->转Number: parse()

    isEmpty判断变量是否为空: if(str.isEmpty){print(‘str为空’);}
    判断变量是否为NaN: if(str.isNaN){print(‘str为NaN’);}

    4、List Set Map以及循环语句forEach、where、why、every

    List常用属性和方法:
    常用属性:
    length 长度
    reversed 翻转
    isEmpty 是否为空
    isNotEmpty 是否不为空
    常用方法:
    add 增加
    addAll 拼接数组
    indexOf 查找 传入具体值
    remove 删除 传入具体值
    removeAt 删除 传入索引值
    fillRange 修改
    insert(index,value) 指定位置插入
    insertAll(index,list) 指定位置插入list
    toList() 其他类型转list
    join() list转字符串
    split() 字符串转list
    forEach

    数组去重的一种方式:

    var l = ['葡萄','香蕉','葡萄','苹果','桃子','桃子','猕猴桃','大枣','蜜瓜'];
    var s = new Set();
    s.addAll(l);
    print(s);
    print(s.toList());
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5、函数相关

    内置方法/函数:
    print();
    自定义方法:
    基本格式:

    返回类型 方法名称(int/String 参数1,参数2,...){
    	方法体
    	return 返回值
    }
    
    • 1
    • 2
    • 3
    • 4

    注:
    1、自定义方法定义可以在入口方法内定义,也可以在外定义;但是最终调用时需要在入口函数内部;函数也有作用域,
    2、如果不知道返回值是什么,函数名前面可以不写返回类型,但如果知道尽量写上去;
    3、方法传参数的时候尽量也给参数写上类型,这样避免不必要的错误;当然也可以不传的;
    4、可选参数、默认参数,如下函数:
    5、命名参数,如下:
    6、把方法当作参数的方法,如下:

    // 可选参数、默认参数
    String printUserInfo(String username, [String sex='女', int age]){
    	...
    }
    printUserInfo('小明', '女'); // 调用
    
    
    // 命名参数
    String printUserInfo(String username, {String sex='女', int age}){
    	...
    }
    printUserInfo('小明', age:30); // 调用
    
    // 把方法当作参数的方法
    fn1(){
    	print('我是fn1打印出来的数据');
    }
    fn2(fn){fn();}
    
    fn2(fn1); // 调用
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    7、箭头、匿名、闭包函数

    // 定义一个方法判断一个数是否是偶数;
    // 定义一个函数打印1-n所有的偶数。
    bool isEvenNumber(int n){
    	if(n%2==0){
    		return true;
    	}
    	return false;
    }
    
    printNum(int n){
    	for(var i=1; i<=n; i++){
    		if(isEvenNumber(i)){
    			print(i);
    		}
    	}
    }
    printNum(10);  // 调用
    
    // 匿名函数:
    var printNum2 = (){
    	print('我是匿名函数结果');
    }
    printNum2();
    
    // 自执行函数
    ((int n){
    	print(n);
    })(12)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    6、对象、类

    面向对象开发:继承、封装、多态

    dart所有的东西都是对象,所有的对象都继承自object类。
    dart是一门使用类和单继承的面向对象语言,多有的对象都是类的实例,并且所有的类都是object的子类;
    一个类通常由属性和方法组成。

    构造函数:默认构造函数、命名构造函数
    类class名称的首字母需大写

    // 普通
    class PersonMsg{
    	String name='某人';
    	int age=22;
    	void printInfo(){
    		print('${this.name}----------${this.age}');
    	}
    }
    // 含有构造方法(函数一运行实例化时就会执行的事件即构造函数)
    class PersonMsg2{
    	String name='某人';
    	int age=22;
    	PersonMsg2(){ // 默认构造函数名称和类名一致
    		print('这是构造函数里面的内容,实例化时立即会执行');
    	}
    	void printInfo(){
    		print('${this.name}----------${this.age}');
    	}
    }
    class PersonMsg3{
    	String name;
    	int age;
    	// 默认构造函数
    	// PersonMsg3(String name, int age){
    	//	this.name = name;
    	//	this.age = age;
    	//}
    	// 默认构造函数简写形式
    	PersonMsg3(this.name, this.age);
    	// 命名构造函数 (默认构造函数只能有一个;命名构造函数可以有多个)
    	PersonMsg3.sum(){
    		print('我是命名构造函数');
    	}
    	void printInfo(){
    		print('${this.name}----------${this.age}');
    	}
    }
    void main(){
    	PersonMsg p1 = new PersonMsg(); // 实例化
    	print(p1.name);
    	p1.printInfo();
    
    	PersonMsg2 p2 = new PersonMsg2(); // 实例化 此时就会打印出‘这是构造函数里面的内容,实例化时立即会执行’
    
    	PersonMsg3 p3 = new PersonMsg3('瓦格纳', 33); // 实例化
    	p3.printInfo();
    	PersonMsg3 p4 = new PersonMsg3('李四', 23); // 可以多次实例化
    	p4.printInfo();
    	PersonMsg3 p5 = new PersonMsg3.sum(); // 此时就会打印出'我是命名构造函数'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    注:
    Dart和其他面向对象的语言不一样,没有public、private、protected等设置变量为私有或公有的;
    Dart中一般使用_把一个属性或则方法定义成私有的。(ps:使用这种方式必须把该变量提出去不能在一个文件内才会生效!)

    dart中可以有默认值,即在构造函数执行之前初始化实例变量

    class Rect{
    	int height;
    	int width;
    	Rect():height=2,width=10{
    		print("${this.height}-----${this.width}");
    	}
    	getArea(){
    		return this.height*this.width;
    	}
    }
    void main(){
    	Rect r = new Rect(); // 实例化  print里面的内容会打印出height的值,说明赋值先于构造函数执行之前。
    	print(r.getArea());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    7、类、静态成员、操作符、类的继承

    对象操作符:
    ? 条件运算符:一般用于获取对象中某一变量时,防止该对象下没有此变量。如userInfo?.name
    as 类型转换
    is 类型判断
    … 级联操作(连缀操作)

    • 在变量或函数前面添加static及表示为静态变量或方法。不用实例化,直接用类名就可以调用静态方法变量,实例化后只能获取非静态数据。
    • 静态成员不能访问非静态成员;反之非静态成员可以访问静态成员;

    类的继承:子类可以继承、扩展父类方法,还可以重写父类方法

    class People {
    	String name;
    	num age;
    	People(this.name,this.age);
    	void printInfo(){
    		print('${this.name}------${this.age}');
    	}
    }
    class Web extend People{ 
    	String sex; // 如果有新的参数可以定义
    	Web(String name, num age, String sex): super(name,age){    // 类Web继承于People,因为类People有参数,所以Web也应该设置
    		this.sex = sex;
    	}
    	run(){ // Web自己自定义函数
    		print('${this.name}------${this.age}-----${this.sex}');
    	}
    	@override   // 建议复写父类方法时添加这个关键字,也可以不加
    	void printInfo(){
    		print('姓名:${this.name}------年龄:${this.age}');
    	}
    }
    
    main() {
    	Web web1 = new Web('小李', 20, '男');
    	web1.printInfo(); // 小李------20
    	web1.run(); // 小李------20-----男
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    注: 如果是命名构造函数也是可以的,父类变成People.xxxx(this.name,this.age);
    子类变成Web(String name, num age, String sex): super.xxxx(name,age){}

    8、抽象类、 多态 、接口

    抽象类abstract:主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。

    在这里插入图片描述

    多态:就是父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的表现。
    接口:关键字implements 定义规范的。

    extends抽象类 和 implements的区别:
    1、如果要复用抽象类里面的方法,并且要用抽象方法约束子类的话我们就用extends继承抽象类;
    2、如果只是把抽象类当作标准的话我们就用implements实现抽象类。

    一个类实现多个接口
    abstract class A {
    	String name;
    	printA();
    }
    abstract class B {
    	printB();
    }
    
    class C implements A,B {  // 可以多接口
    	@override
    	String name;
    	@override
    	printA(){print('printA');}
    	@override
    	printB(){return null;}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    注:可以多接口 不能多继承;所以又有一个新的属性Mixins

    9、Mixins

    关键字是with
    注意:
    1、作为mixins的类只能继承自Object,不能继承其他类;(如下面的A B类不能extends继承其他的类)
    2、作为mixins的类不能有构造函数;(如下面的A B类不能写构造函数,如果A类里必须有构造函数,则可以写出class C extents A width B 这样就可以实现了。)
    3、一个类可以mixins多个mixins类;
    4、继承或mixins按顺序,如果有相同的方法和属性时,后面的会覆盖前面的;
    5、mixins绝不是继承,也不是接口,而是一种全新的特性。

    class A {
    	String name;
    	printA(){print('printA');}
    }
    class B {
    	printB(){return null;}
    }
    
    class C width A,B { // 类C中包含A B当中所有的属性和方法
    }
    
    main(){
    	C c = new C();
    	c.printA();
    	c.printB();
    	print(c.name);
    	// 类型
    	print(c is C); // true
    	print(c is A); // true
    	print(c is B); // true
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    10、泛型、泛型类、泛型方法、泛型接口

    函数代码冗余,合并。

    class MyList<T> {
    	List list = <T>[];
    	void add(T value){
    		this.list.add(value);
    	}
    	List getList() {
    		return list;
    	}
    }
    
    main(){
    	MyList list = new MyList<int>();
    	list.add(12);
    	list.add(33);
    	print(list.getList());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    11、自定义库、系统库、第三方库的使用

    1、只使用库中有部分隐藏、部分使用的功能:hide show
    如:import ‘http://xxxx.c’ hide foo;

    1、空安全:? 可空类型

    // 变量
    String? username = '张三';  // String?  表示username是一个可空类型;  如果不加?号就会报错
    username = null;
    print(username);
    
    // 函数
    String? getData(apiUrl){ // 如果不加问号,就不能返回null
    	if(apiUrl!=null){
    		return "this is server data";
    	}
    	return null;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2、类型断言 :!
    3、late: 关键词主要是为了延迟初始化
    4、required: 必传参数

  • 相关阅读:
    代码整洁之道-读书笔记之函数
    webpack5 打包环境抽离分环境基本配置
    Spring学习(2) Spring的IOC底层实现
    leetcode-每日一题-764-最大加号标志(中等,dp)
    JAVA安装教程 (windows)
    用户级协议和框架:DPDK、SPDK和VPP的业务场景和发展趋势
    深入理解数组
    【LeetCode】145. 二叉树的后序遍历 [ 左子树 右子树 根结点]
    【OpenDDS开发指南V3.20】第四章:条件和监听
    Java 解决约瑟夫问题的示例代码
  • 原文地址:https://blog.csdn.net/yongyafang123/article/details/126519226