Flutter学习总结(二)开发语言Dart学习

语言都是相通的,Dart语言也不例外,对比,参考尤为重要。

注释

单行注释:

// todo 一般针对某一语句进行注释。

多行注释:

/*
* 针对一段逻辑可以多行解释,但是这种用的不多,
* 大部分都是采用文档注释的方式进行多行注释。
*/

文档注释:

/// 主要针对类、全局变量和方法上进行注释。
///
/// 在第一句之后添加一个空行,将其拆分为自己的段落,这有助于您编写一个简短的第一句话来总结文档。
///
/// 尽量在文档注释中使用方括号来引用范围内标识符,例如[Flag]、[addFlag]、[name]甚或是其他类成员[LoginPage.userName]都行。
///
/// 可以在注释中引用代码,例如:
/// ```dart
/// Flag addFlag(String name, String abbr) => ...
/// ```
Flag addFlag(String name, String abbr) => ...

变量与常量

变量

1.通用类型var

var可以自动推断出变量类型,常用于定义对象。

var str = '123';
var userInfo = LoginInfo.fromJson(xxx);
2.字符串
/// 单一赋值
String str = '123';

/// 多行赋值
String str1='''
  hello word,
  hello dart!
  ''';

/// 字符串拼接
String s = '456';
String str = '123$s789'; 
print('$str0'); //1234567890
3.数字类型
/// 数值型使用关键字[num]表示,它包含整型[int]和浮点型[double]两种。
num i = 123.45;

/// 整形
int i1 = 123;

/// 浮点型
double i2 = 123.45;
4.布尔类型bool
bool flag = true;
5.List

List既可以表示集合也可以表示数组。

/// list定义
var l = [];
var l0 = <int>[]; 
List l1 = List(); 
List l2 = List<int>(); // 指定存放类型
List l3 = List.filled(2, "");  // 生成一个固定长度的集合
List l4 = List<String>.filled(2, ""); // 生成一个固定数据类型固定长度的集合

/// 取值
int a = l2[0];

/// list去重,先定义一个set,再把list塞到set里。
var repeat = ['aa', 'bb', 'cc', 'aa', 'bb'];
var dedu = Set();
List list = dedu.addAll(repeat).toList();

/// list foreach
list.forEach((value){
print('$value');
})

/// list重组两种方式
var list = list.map((value){
return value*2;
})
var list = list.where((value){
return value>5;
})


/// list包含判断
// 只要有一个满足条件的返回true
bool f = list.any((value){
return value >5;
})
// 每一个都满足返回true
bool f = list.every((value){
return value>5;
})
6.Map
/// map定义
var map = {};
Map map1 = Map();
var person={
    'name':'张三',
    'age':20
  };

/// map取值
String name = person['name'];

/// map赋值
person['age'] = 21;

/// 获取所有key
List keys = person.keys.toList();

/// 获取所有value
List values = person.values.toList();

/// map添加数据
person.addAll({
'sex':'男'
});

/// 是否包含某个值
person.containsValue('张三');

/// map foreach
map.forEach((key, value){
print("$key---$value");
})
其他
// late修饰,表示a一定会初始化,只不过稍后处理。
late int a; 

// dynamic表示任意类型,类似java中的Object
Map<String, dynamic> map;

常量

// 编译期常量,一般用“static const”修饰,表示不可修改
const PI = 3.14159; 

// 惰性初始化常量,和java的final类似,常用来修饰对象,确保对象不容易修改。
final pi;
pi = 3.14159;

空安全

空安全在代码编辑阶段帮助我们提前发现可能出现的空异常问题,但这并不意味着程序不会出现空异常。

// 明确表示a不能为空
int a; 
// 代码编写过程中不可以直接赋值null,否则直接报红
// a = null; //错误写法

// 允许b为空
int? b;
b = null; // 允许程序编写和编译,但不保证编译运行后报错。

// 对象属性调用
UserInfo? userInfo = UserInfo.fromJson(...);
// String? name = userInfo.name; // 错误写法,因为userInfo有可能为空,所以编译器不允许直接调用。
String? name = userInfo?.name; // 正确写法
String? name = userInfo!.name; // 正确写法,此时开发完全需要保证userInfo不为空,不推荐,迫不得已采用。
String name = userInfo?.name??''; // name有可能为空,但是接收对象是不允许为空的,所以如果为空给一个默认值。

运算符与类型转换

运算符

“非”、“算术”、“关系”、“条件”、“逻辑”、“赋值”、“逗号”七种运算符使用和Java大差不差。

赋值判空"??"

String name = userInfo?.name ?? '';

类型判断和转换

/// 类型判断
if(b is String){
print('b是字符串类型')
}

/// as 强转
var p = getPersion();
if(p is Person){
    (p as Person).printInfo();
}

/// 字符串转int
int myNum=int.parse('123');

/// 数字转String
String str = num.toString();

/// Dart中0可以作为被除数,不会报错,并且打印出Nan,可以用此判断是否是被除数为0.
var a=0/0;
print(a);//打印出Nan,不会报错

遍历

/// for循环除了常规的"fori"形式还有"for in".
for(var item in List){
print(item);
}

函数

/// 可选参数,方括号里面的参数都是可选参数,可以定义默认值
String getPersonInfo(String name, [int age=20, String sex]){
    // todo ...
    return '';
}

/// 把一个方法当作参数,常用于回调
fun1(){
  print("fun------");
}
fun2(fun){
  fun();
}

/// 箭头函数(lambda表达式),注意箭头函数只能有一条语句
list.forEach((value)=>print("value=$value"));

/// 匿名函数
var printNum2=(int i){
    print(i);
  };
printNum2(123);

/// 闭包
///
/// 问题:
/// 1.全局变量特点:全局变量常驻内存、全局变量污染全局
/// 2.局部变量的特点:不常驻内存会被垃圾机制回收,不会污染全局
///
/// 需求:
/// 1.局部变量常驻内存
/// 2.不污染内存
/// 
/// 闭包可以解决。闭包:函数嵌套函数,内部函数会调用外部函数的变量或参数,变量或参数不会被系统回收(不会释放内存)。
/// 闭包写法:函数嵌套函数,并return 里面的函数,这样就形成了闭包
void main(){
  //闭包
  fun(){
    var a=123;
    return(){
      a++;
      print(a);
    };
  }
 
  var b=fun();
  b();//124
  b();//125
  b();//126
}

/// 常规构造函数,和java一样
class Person{
    int age;
    String name;
    Person(int age, String name){
        this.age = age;
        this.name = name;
    }
}

/// 构造函数简写
class Person{
    int age;
    String name;
    Person(this.age, this.name){
    }
}

/// 命名构造函数
class Person{
    int age;
    String name;
    Person(this.age, this.name){
    }

    Person.info(){
        print('age=$age,name=$name');
    }
    
    /// 命名构造函数可以有多个
    Person.setAge(this.age){
        print("setAge age=$age");
    }
}

/// getter和setter修饰符
class Person{
    int age;
    String name;
    Person(this.age, this.name){
    }
    
    /// 可直接通过属性的方式访问,例如 p.theAge,
    get theAge{
        return age;
    }
    /// p.forName('张三');
    set forName(str){
        this.name = str;
    }
}

/// 级联(链式)调用(对象可以连续调用他的属性或方法)
class Person{
    int age;
    String name;
    Person(){
        this
          ..age = 20
          ..name = '张三';
    }
}

/// 抽象类
/// 1. dart中的抽象方法不能用abstract声明,Dart中没有方法体的方法我们称为抽象方法;
/// 2. 抽象类用extends继承
abstract class Animal{
  /// 抽象方法,无方法体,子类必须实现
  eat();
  /// 普通方法
  printInfo(){
    print('我是一个抽象类里面的普通方法');
  }
}

/// 接口
/// 1. dart的接口没有interface关键字定义接口,而是普通类或抽象类都可以作为接口被实现。
/// 2. 接口类使用implements关键字进行实现,会将普通类和抽象中的属性的方法全部需要覆写一遍。
/// 3. 建议使用抽象类定义接口。因为抽象类可以定义抽象方法,普通类不可以,所以一般如果要实现像Java接口那样的方式,一般会使用抽象类。
abstract class Animal{
  eat();
}
class Persion implements Animal{
    @override
    eat(){
        print('吃榴莲');
    }
}

/// mixins多继承
/// mixins类可以实现多继承,目的就是在一个类中混入其他类的功能。
/// 1. mixins的类只能继承自Object,不能继承其他类。
/// 2. 作为mixins的类不能有构造函数
/// 3. mixins类可以用mixins代替class声明一个mixin类,也可以用普通的类(继承自Object)作为mixins类
/// 4. 当继承的多个类中有同样的方法时,谁排在最后则调用谁的函数。
/// 5. 子类多继承采用with关键字来实现
mixin A {
  String info="this is A";
  void printA(){
    print("A");
  }
}

class B {
  void printB(){
    print("B");
  }
}
class C with A,B{
  
}

/// 泛型,和java使用类似,不在多说
...

私有方法和私有属性

在属性或者方法名前加_表示私有。

int _age=2;
void _getName(){
    return name;
}

引入库采用import字段引入,一个dart文件就是一个库,因此平时开发时在一个dart文件中引入另外一个dart文件方法或属性就要引库。

例如 lib/person.dart:

void getName(){
  print('张三');
}
void getAge(){
  print(20);
}
void getSex(){
  print('男');
}

引入库场景:

/// 普通引入
import 'package:lib/person.dart';

/// 冲突解决,当引入两个库中有相同名称标识符的时候会发生冲突,可使用as关键字来指定库的前缀。
import 'package:lib/person1.dart' as person1;

/// 部分导入,如果只需要导入库的一部分,有两种模式:
/// 1. 只导入需要的部分,使用show关键字
/// 2. 隐藏不需要的部分,使用hide关键字
import 'lib/person.dart' show getAge;  
import 'lib/person.dart' hide getName;  

异步

dart是单线程,不能向java一样开启多个线程,dart的异步采用asyncawait来修饰。

  • async是让方法变成异步。
  • await是等待异步方法执行完成。

注:只有async方法才能使用await关键字调用方法

void main(){
  var result = await testAsync();
  print(result);
}

/// 获取async修饰的返回值采用Future类型接收,不写的话,默认也会给一个Future类型
Future<String> testAsync() async{
  return 'Hello async';
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值