Dart学习笔记(5)--泛型、库、 async和await、导入pub包管理系统和冲突解决、部分导入和延迟加载、Dart 新特性

01、泛型方法


通俗理解:泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持(类型校验)

//只能返回string类型的数据

  String getData(String value){
       return value;
   }
  

//同时支持返回 string类型 和int类型  (代码冗余)

   String getData1(String value){
       return value;
   }

   int getData2(int value){
       return value;
   }



//同时返回 string类型 和number类型       不指定类型可以解决这个问题

  getData(value){
     return value;
   }



//不指定类型放弃了类型检查。我们现在想实现的是传入什么 返回什么。比如:传入number 类型必须返回number类型  传入 string类型必须返回string类型
 
   T getData<T>(T value){
       return value;
   }

  getData<T>(T value){
      return value;
  }

void main(){

    // print(getData(21));

    // print(getData('xxx'));

    // getData<String>('你好');

    print(getData<int>(12));

}

02、泛型类

//集合List 泛型类的用法

//案例:把下面类转换成泛型类,要求MyList里面可以增加int类型的数据,也可以增加String类型的数据。但是每次调用增加的类型要统一

/*
class MyList {
  List list = <int>[];
  void add(int value) {
    this.list.add(value);
  }
  List getList() {
    return list;
  }
}

MyList l = new MyList();
l.add(1);
l.add(12);
l.add(5);
print(l.getList());

*/

class MyList<T> {
  List list = <T>[];
  void add(T value) {
    this.list.add(value);
  }

  List getList() {
    return list;
  }
}

main() {
  // MyList l1=new MyList();
  // l1.add("张三");
  // l1.add(12);
  // l1.add(true);
  // print(l1.getList());

  // MyList l2 = new MyList<String>();
  // l2.add("张三1");
  // // l2.add(11);  //错误的写法
  // print(l2.getList());

  MyList l3 = new MyList<int>();
  l3.add(11);
  l3.add(12);
  l3.add("aaaa");
  print(l3.getList());



  

  // List list = List.filled(2, "");
  // list[0] = "张三";
  // list[1] = "李四";
  // print(list);

  // List list = new List.filled(2, "");
  // list[0] = "张三1";
  // list[1] = "李四";
  // print(list);

  // List list = new List<String>.filled(2, "");
  // list[0] = "张三1";
  // list[1] = "李四";
  // print(list);

  //  List list2 = new List<int>.filled(2, 0);
  //   list2[0] = 12;
  //   list2[1] = 13;
  //   print(list2);
}

03、泛型接口

/*
Dart中的泛型接口:

    实现数据缓存的功能:有文件缓存、和内存缓存。内存缓存和文件缓存按照接口约束实现。

    1、定义一个泛型接口 约束实现它的子类必须有getByKey(key) 和 setByKey(key,value)

    2、要求setByKey的时候的value的类型和实例化子类的时候指定的类型一致


*/


  // abstract class ObjectCache {
  //   getByKey(String key);
  //   void setByKey(String key, Object value);
  // }

  // abstract class StringCache {
  //   getByKey(String key);
  //   void setByKey(String key, String value);
  // }


  // abstract class Cache<T> {
  //   getByKey(String key);
  //   void setByKey(String key, T value);
  // }


abstract class Cache<T>{
  getByKey(String key);
  void setByKey(String key, T value);
}

class FlieCache<T> implements Cache<T>{
  @override
  getByKey(String key) {    
    return null;
  }

  @override
  void setByKey(String key, T value) {
   print("我是文件缓存 把key=${key}  value=${value}的数据写入到了文件中");
  }
}

class MemoryCache<T> implements Cache<T>{
  @override
  getByKey(String key) {   
    return null;
  }

  @override
  void setByKey(String key, T value) {
       print("我是内存缓存 把key=${key}  value=${value} -写入到了内存中");
  }
}
void main(){


    // MemoryCache m=new MemoryCache<String>();

    //  m.setByKey('index', '首页数据');


     MemoryCache m=new MemoryCache<Map>();

     m.setByKey('index', {"name":"张三","age":20});
}

04、Dart中的库



前面介绍Dart基础知识的时候基本上都是在一个文件里面编写Dart代码的,但实际开发中不可能这么写,模块化很重要,所以这就需要使用到库的概念。

在Dart中,库的使用时通过import关键字引入的。

library指令可以创建一个库,每个Dart文件都是一个库,即使没有使用library指令来指定。


Dart中的库主要有三种:

    1、我们自定义的库     
          import 'lib/xxx.dart';
    2、系统内置库       
          import 'dart:math';    
          import 'dart:io'; 
          import 'dart:convert';
    3、Pub包管理系统中的库  
        https://pub.dev/packages
        https://pub.flutter-io.cn/packages
        https://pub.dartlang.org/flutter/

        1、需要在自己想项目根目录新建一个pubspec.yaml
        2、在pubspec.yaml文件 然后配置名称 、描述、依赖等信息
        3、然后运行 pub get 获取包下载到本地  
        4、项目中引入库 import 'package:http/http.dart' as http; 看文档使用

05、Dart中的async和await



asyncawait
  这两个关键字的使用只需要记住两点:
    只有async方法才能使用await关键字调用方法
    如果调用别的async方法必须使用await关键字


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



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

}

//异步方法
testAsync() async{
  return 'Hello async';
}



06、导入pub包管理系统和冲突解决

/*
pub包管理系统:


1、从下面网址找到要用的库
        https://pub.dev/packages
        https://pub.flutter-io.cn/packages
        https://pub.dartlang.org/flutter/

2、创建一个pubspec.yaml文件,内容如下

    name: xxx
    description: A new flutter module project.
    dependencies:  
        http: ^0.12.0+2
        date_format: ^1.0.6

3、配置dependencies

4、运行pub get 获取远程库

5、看文档引入库使用
*/
import 'dart:convert' as convert;
import 'package:http/http.dart' as http;
import 'package:date_format/date_format.dart';

main() async {
  // var url = "http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1";

  //   // Await the http get response, then decode the json-formatted responce.
  //   var response = await http.get(url);
  //   if (response.statusCode == 200) {
  //     var jsonResponse = convert.jsonDecode(response.body);
     
  //     print(jsonResponse);
  //   } else {
  //     print("Request failed with status: ${response.statusCode}.");
  //   }


  
    print(formatDate(DateTime(1989, 2, 21), [yyyy, '*', mm, '*', dd]));

}







1、冲突解决
当引入两个库中有相同名称标识符的时候,如果是java通常我们通过写上完整的包名路径来指定使用的具体标识符,甚至不用import都可以,但是Dart里面是必须import的。当冲突的时候,可以使用as关键字来指定库的前缀。如下例子所示:

    import 'package:lib1/lib1.dart';
    import 'package:lib2/lib2.dart' as lib2;


    Element element1 = new Element();           // Uses Element from lib1.
    lib2.Element element2 = new lib2.Element(); // Uses Element from lib2.



import 'lib/Person1.dart';
import 'lib/Person2.dart' as lib;

main(List<String> args) {
  Person p1=new Person('张三', 20);
  p1.printInfo();


  lib.Person p2=new lib.Person('李四', 20);

  p2.printInfo();

}

07、部分导入和延迟加载


部分导入
  如果只需要导入库的一部分,有两种模式:

     模式一:只导入需要的部分,使用show关键字,如下例子所示:

      import 'package:lib1/lib1.dart' show foo;

     模式二:隐藏不需要的部分,使用hide关键字,如下例子所示:

      import 'package:lib2/lib2.dart' hide foo;      



// import 'lib/myMath.dart' show getAge;

 import 'lib/myMath.dart' hide getName;

void main(){
//  getName();
  getAge();
}


延迟加载

    也称为懒加载,可以在需要的时候再进行加载。
    懒加载的最大好处是可以减少APP的启动时间。

    懒加载使用deferred as关键字来指定,如下例子所示:

    import 'package:deferred/hello.dart' deferred as hello;

    当需要使用的时候,需要使用loadLibrary()方法来加载:

    greet() async {
      await hello.loadLibrary();
      hello.printGreeting();
    }

08、Dart 新特性

/*
  Null safety翻译成中文的意思是空安全。

  null safety 可以帮助开发者避免一些日常开发中很难被发现的错误,并且额外的好处是可以改善性能。

  Flutter2.2.0(2021年5月19日发布) 之后的版本都要求使用null safety。

  ? 可空类型

  ! 类型断言

*/

String? getData(apiUrl){
  if(apiUrl!=null){
    return "this is server data";
  }
  return null;
}

// void printLength(String? str){
//   // print(str!.length);
//   if (str!=null){
//     print(str.length);
//   }
// }

void printLength(String? str){
  try {
    print(str!.length); 
  } catch (e) {
     print("str is null"); 
  }
}

void main(args) {

//1、 ? 可空类型


  // int a=123;
  // print(a);
  
  // String username="张三";
  // print(username);

  // List<String> l1=["张三","李四","王五"];
  // print(l1);


  // int a=123;  //非空的int类型
  // a=null;  //A value of type 'Null' can't be assigned to a variable of type 'int'


  // String username="张三";  //非空的String类型
  // username=null;   //A value of type 'Null' can't be assigned to a variable of type 'String'.


  // String? username="张三";   // String?  表示username是一个可空类型
  // username=null;
  // print(username);


  // int? a=123;  //  int? 表示a是一个可空类型
  // a=null; 
  // print(a);


  // List<String> l1=["张三","李四","王五"];
  // l1=null;  //A value of type 'Null' can't be assigned to a variable of type 'List<String>'.


  // List<String>? l1=["张三","李四","王五"];
  // l1=null;  
  // print(l1);


  //调用方法
  // print(getData("http://www.itying.com"));

  // print(getData(null));


// ! 类型断言

  // String? str="this is str";

  // str=null;

  // print(str!.length);  
  
   //类型断言: 如果str不等于null 会打印str的长度,如果等于null会抛出异常

  //  printLength("str");
  
   printLength(null);
}


/*
Null safety翻译成中文的意思是空安全。

late 关键字主要用于延迟初始化。

*/
class Person {
  late String name;
  late int age;

  void setName(String name, int age) {
    this.name = name;
    this.age = age;
  }

  String getName() {
    return "${this.name}---${this.age}";
  }
}

void main(args) {
  Person p = new Person();
  p.setName("张三", 20);
  print(p.getName());
}



/*
Null safety翻译成中文的意思是空安全。

required翻译成中文的意思是需要、依赖

required关键词:

    最开始 @required 是注解
    
    现在它已经作为内置修饰符。
    
    主要用于允许根据需要标记任何命名参数(函数或类),使得它们不为空。因为可选参数中必须有个 required 参数或者该参数有个默认值。

*/
String printUserInfo(String username, {int age=10, String sex="男"}) {//行参    
  return "姓名:$username---性别:$sex--年龄:$age";
}

String printInfo(String username, {required int age, required String sex}) {//行参    
  return "姓名:$username---性别:$sex--年龄:$age";
}


// name 可以传入也可以不传入   age必须传入
class Person {
  String? name;   //可空属性
  int age;
  Person({this.name,required this.age});  //表示 name 和age 必须传入

  String getName() {
    return "${this.name}---${this.age}";
  }
}



void main(args) {
    print(printUserInfo('张三'));

    print(printUserInfo('张三',age: 20,sex: "女"));
    
    //age 和 sex必须传入
    print(printInfo('张三',age: 22,sex: "女"));
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值