Dart常用核心知识
Dart简述
Dart 是一个为全平台构建快速应用的客户端优化的编程语言,免费且开源。
Dart是面向对象的、类定义的、单继承的语言。它的语法涵盖了多种语言的语法特性,如C,JavaScirpt, Java, Swift等语言,可以转译为JavaScript,支持接口(interfaces)、混入(mixins)、抽象类(abstract classes)、具体化泛型(reified generics)、可选类型(optional typing)和sound type system。
下面整理了Dart这门语言的核心知识点。
1.变量声明
2.字符串
3.集合
4.函数
5.赋值运算符
6.面向对象
7.枚举
8.库的使用
1.变量的声明
dart变量的声明有两种,常量和变量。使用常量可以保证在定义一个变量后,如果后面赋值了不同的类型的值,会在编译期报错,提高安全性。
常量
1.const编译时常量,这种常量值要在编译前确定。
2.final运行时常量,这种常量值可以在运行时再确定。
变量
1.显示声明,如使用String name定义变量。
2.var类型推导,有编译器自动推导。虽然使用的var定义变量,此时的变量依然是确定的类型。
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 | void main(List<String> args) { print( "Hello Dart" ); // 显示声明 String name = 'jack' ; // 类型推断:类型推断的,也是有类型的。不同类型之间不能赋值。 // 类型推断变量 var age = 20; age = 30; // age = 30.3; // 编译期常量 const school = '北京大学' ; // 运行时常量 final local = DateTime.now(); const p1 = const Person( 'Tom' ); const p2 = const Person( 'Tom' ); const p3 = const Person( 'LiLei' ); print(identical(p1, p2)); print(identical(p1, p3)); } class Person { final String name; // 构造函数传参直接赋值到name属性上。 const Person( this .name); } |
2.字符串
定义字符串有三种方式:单引号,双引号,三引号。
字符串的拼接规则和shell语法一样,$变量名后面没有其他符号时使用$变量名,后面紧跟其他符号产生歧义时,使用${变量名}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | void main(List<String> args) { // 定义字符串三种方式:单引号,双引号,三引号 var str1 = 'abc' ; var str2 = "def" ; var str3 = "" " ghi jkl mn " "" ; print(str3); // 字符串拼接: 拼接规则和shell很相似 var name = 'jack' ; var age = 30; var height = 190.3; var msg1 = "name is $name, age is ${age}, height is ${height}, height Type is ${height.runtimeType}" ; print(msg1); } |
3.集合
dart中有三种集合, dart在集合中广泛使用泛型来表示集合中存放的是什么类型。
1.列表List: 使用[‘ABC’]进行定义
2.集合Set: 使用{'abc'}, 可以对列表List去重
3.哈希Map: 使用{'name': value},使用的键值对进行定义
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 | void main(List<String> args) { // dart中没有关键字定义接口,默认情况下,所有的class都是隐式接口 // dart在集合中广泛使用泛型来表示集合中存放的是什么类型。 // 1.列表List var names = [ 'abc' , 'cba' , 'nba' , 'cba' , 'abc' ]; names.add( 'hhh' ); print(names); print(names.runtimeType); // 2.集合Set var movies = { '星际穿越' , '大话西游' , '盗梦空间' }; names = Set<String>.from(names).toList(); print(names); print(movies); // 3.映射Map // 映射的Key应该是可以求出hash值的。 var info = { 'name' : 'jack' , 'age' : 30 }; Map; print(info); print(info.runtimeType); } |
4.函数
函数的定义
dart 函数的形式和 C 语言相似,形式为:返回值 函数名(参数) {函数体}
其中返回值部分可以省略有编译器自动推导,但是推荐写上,方便开发人员理解。
dart 中没有函数的重载。
函数的可选参数
可选参数类型有:位置可选参数 、命名可选参数两种。
位置可选参数形式为:[int age, double height],实参和形参在进行匹配时,是根据位置匹配的。
命名可选参数:{int age, double height},实参和形参在进行匹配时,需要根据名称进行设置。
可选参数可以有默认值,必传参数不能设置默认值。
函数是一等公民
一等公民是很灵活的,可以作为参数和返回值。
OC 中使用 Block 实现这一特性。
匿名函数
因为 dart 中函数为一等公民,所以在函数作为参数进行传参时,可以将函数写成匿名函数的形式。
参数中的匿名函数有两种形式:
匿名函数体是单条语句时,可以用是箭头函数表示
testFunc(() => print('箭头匿名函数,只能有一条语句') );
当匿名函数体中的语句多行时,使用下面的形式
1 2 3 4 | // 多条语句 testFunc(() { print( '匿名函数被调用' ); }); |
匿名传参,参数需要定义为完整的函数签名,也可以使用下面类型定义的方式。
1 2 3 4 | typedef Calculate = int Function(int num1, int num2); void testFoo2(Calculate cal) { cal(10, 10); } |
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | void main(List<String> args) { print(sayHi(10, 20)); // 顺序可选参数,传参的顺序必须和定义顺序相同 sayHello1( 'jack' , 30); // 命名可选参数,传参需要带定义的名称 sayHello2( 'jack' , age: 30); testFunc(foo); } // 1.函数的定义 // 返回值类型int 可以省略,但是推荐保留 int sayHi(int height, int age) { return age + height; } // 2.函数的可选参数 /* dart中没有函数的重载 可选参数:位置可选参数 - 命名可选参数 可选参数可以默认值,必传参数不需要默认值 */ // 位置可选参数 void sayHello1(String name, [int age, double height]) { } // 命名可选参数 void sayHello2(String name, {int age, double height}) { } // 命名可选参数带默认值 void sayHello3(String name, {int age, double height = 12}) { } // 3.函数是一等公民 /* 一等公民是很灵活的,可以作为参数和返回值。 OC中使用Block实现这一特性 */ void testFunc(Function foo) { foo(); } void foo() { print( 'foo 函数被调用' ); } // 4.匿名函数 void testFunc2() { // 多条语句 testFunc(() { print( '匿名函数被调用' ); }); // 单条语句 testFunc(() => print( '箭头匿名函数,只能有一条语句' ) ); // 匿名函数传参 /* 匿名传参,参数需要定义为完整的函数签名:void testFoo(int foo(int num1, int num2)) {} */ testFoo((num1, num2) => num1 + num2); testFoo2((num1, num2) => num1 + num2); // 匿名返回值 var foo3 = testFoo3(); foo3(3, 3); } void testFoo(int foo(int num1, int num2)) { print(foo(10, 20)); } typedef Calculate = int Function(int num1, int num2); void testFoo2(Calculate cal) { cal(10, 10); } Calculate testFoo3() { return (int num1, int num2) => num1 * num2; } |
5.赋值运算符
Dart中比较特别的运算符有: ??=, ??, 级联运算符
??=
如果运算符 ??=前面的变量为null就执行后面的=赋值操作,如果pro有值就不执行后面的操作。
特点:可能有赋值操作。
使用场景如:pro ??= name;
??
??是?:三目运算符号的简写, 如果前面的变量有值则取前面的值,如果前面的值为空就取后面的值。
特点:一定有赋值操作。
使用场景如:school = pro ?? '没人上学';
级联运算符..
级联运算符可以连续对实例对象调用方法或属性
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 | void main(List<String> args) { // ??=: 如果前面的pro为null就执行后面的=赋值操作,如果pro有值就不执行后面的操作。 // 可能有赋值操作 var name = 'jim' ; var pro = null ; pro ??= name; print(pro); // ??: 是?:三目运算符号的简写, 如果前面的变量有值则取前面的值,如果前面的值为空就取后面的值。 // 一定有赋值操作 var school = '小学' ; school = pro ?? '没人上学' ; print(school); // 级联运算符:可以连续调用..方法 var p = Person() ..name = 'jim' ..eat() ..run(); p.eat(); } class Person { var name; void eat() { } void run() { } } |
6.面向对象
1.类的基本定义
dart中的类默认继承在Object类,创建的实例对象可以调用Object中的方法。
如果不自定义结构函数,系统会给类自动创建一个空参数的构造函数。
1 2 3 4 5 | // 类默认是继承自Object的,应用创建的对象是可以使用Object中的方法的。 class Person { String name; int age; } |
2.类的构造函数
dart中类的构造函数有三种:
a.用户没有自定义构造函数时,系统会默认实现一个空参数的构造函数
b.普通构造函数,通过便捷赋值,直接初始化属性值
1 | Student( this .name, this .age); |
c.命名构造函数,因为Dart中不支持函数重载,所以出现了命名构造函数来作为构造函数
1 2 3 4 5 6 7 | Student.withNameAgeHeight( this .name, this .age, this .height); Student.withMap(Map<String, dynamic> map) { this .name = map[ 'name' ]; this .age = map[ 'age' ]; this .height = map[ 'height' ]; }; |
dynamic、var、Object的区别?
var是类型推断。
dynamic是类型声明,相当于Swift中的Any,它是一个具体类型的声明,如String。
Object可以父类指向子类对象。
dynamic是运行时报错, Object是编译时报错。
3.类的初始化列表
dart的构造函数的结构体执行时,是在构造函数执行后,所以对于final属性,它必须在构造函数执行时进行执行。所以此时的执行时间需要在结构体执行,故:它的执行时间是在():后面的初始化列表里执行。
初始化列表:里面执行不仅可以包含编辑期静态返回值,还可以包含动态调用返回值。如:Color.blue
可选命名表达式: 只能有编译器静态赋值表达式,如:int age = temp ?? 20
1 2 3 4 5 6 7 8 9 10 | // 3.类的初始化列表 class Teacher { final String name; final int age; // Teacher(this.name, {int age = 10, String color}): this.color = color ?? '' { // } Teacher(): this .name = 'jc' , this .age = 10 { } } |
4.构造函数重定向
当一个类中定义多个构造函数时,可以在普通构造函数的初始化列表中调用其他命名构造函数。
1 2 3 4 5 6 7 8 9 | class Doctor { int age; String name; // 构造函数重定向 Doctor(String name): this ._internal(name, 10); // 命名构造函数 Doctor._internal(String name, int age); } |
5.常量构造函数
使用常量构造函数创建的常量对象,如果对象的属性值一样时,返回的实例对象内存地址是一样的,返回的是同一个对象。
1 2 3 4 5 6 7 | // 5.常量构造函数,相同的属性只有一个内存对象。 class Apple { final String name; final int age; const Apple( this .name, this .age); } |
6.工厂构造函数
工厂构造函数最大的特点是可以手动返回对象。
普通构造函数与工厂构造函数的区别:
普通构造函数不需要写return 会自动返回实例对象。
工厂构造函数需要写return 手动返回实例对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // 6.工厂构造函数:最大的特点可以手动返回一个对象。 class Orange { String name; String color; static final Map<String, Orange> _nameCache = {}; static final Map<String, Orange> _colorCache = {}; factory Orange.withName(String name) { if (_nameCache.containsKey(name)) { return _nameCache[name]; } else { final p = Orange(name, 'red' ); _nameCache[name] = p; return p; } } Orange( this .name, this .color); } |
7.Setter, Getter
在Dart中没有private public等修饰符,当对属性_开头时,表示这个属性是私有属性,只能在当前文件模块内访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // 7.Setter, Getter进行属性监听 // 使用方式是: var e = Elephone(); e.setName('jim'); e.getName class Elephone { String name; // 在Dart中没有private public等修饰符,当对属性_开头时,表示这个属性是私有属性,只能在当前文件模块内访问。 String _age; // setter set setName(String name) { this .name = name; } // getter String get getName { return name; } } |
8.继承
子类继承父类时,父类有构造函数时,需要在子类的参数列表中进行调用,进行初始化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // 8.继承:父类的构造函数要在子类的初始化列表中进行调用。 class Animal{ String name; Animal( this .name); void eat() { print( 'eatting' ); } } class Dog extends Animal { int age; // 父类有构造函数时,需要在参数列表中进行调用,初始化。 Dog( this .age, String name): super (name); } |
9.抽象类
抽象类在使用时有以下特点:
a.子类继承抽象父类,父类的接口方法必须实现,它们都是必选项。因为dart中没有option可选项。
b.抽象类不能被实例化。
c.系统调用抽象类Map进行实例化的过程分析
Map是一个抽象类,而可以调用Map()产生实例对象的原因是因为调用的Map()是Map抽象类的工厂方法 external factory Map();
external关键字 是一个方法存在的声明,表示此方法已经存在,但不在这里实现。这样实现和声明分离
的好处是,可以在实现的地方使用runtimeType集中处理不同平台逻辑,而通过方法接口声明在不同的平台调用。
在方法具体实现的地方使用@patch修饰。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // 9.抽象类 abstract class Shape { int getArea(); String getInfo() { return '形状' ; } void testMap() { final m = Map(); print(m.runtimeType); } } class Rectangle extends Shape { @override int getArea() { return 20; } } |
10.dart隐式接口
dart中定义的class同时也可以当接口使用,可以说class定义的即是类,也是接口。当它做为类使用时,里面定义的方法不必须让子类实现。当它做接口时,里面定义的方法都需要被重新实现。
dart是单继承语言。
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 | // 10.dart隐式接口:dart中定义的class同时也可以当接口使用。 class Runner { void run() { print( 'running' ); } } class Fly { void fly() { print( 'fly' ); } } class SuperMan extends Animal implements Runner, Fly { SuperMan(String name): super (name); // 1.接口实现 @override void run() { // TODO: implement run } @override void fly() { // TODO: implement fly } // 2.方法重写 @override void eat() { // TODO: implement eat super .eat(); } } |
11.混入mixin
dart是单继承语言。
当出现需求想要同时拥有多个类中的方法和属性时,可以通过 混入mixin来间接实现多继承。
可以同时引入多个mixin类中的方法。
dart是单继承, 如果要想同时引入多个mixin类中的方法,则可以定义多个mixin类来引入。
定义用mixin,使用用with。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // 11.混入mixin mixin Play { void play() { print( 'play' ); } } mixin Jump { void jump() { print( 'jump' ); } } class Robbit extends Animal with Play, Jump { Robbit(String name): super (name); @override void eat() { // TODO: implement eat super .eat(); } } |
12.static 类属性,类方法
可以通过static静态声明来定义类属性和类方法/*
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 12. static 类属性,类方法 */ class SuperWoman { // 成员变量,成员方法 var name; void fly() { } // 静态/类变量,静态/类方法 static var flyYear; static void run() { } } |
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | void main(List<String> args) { // 虽然dart支持函数式开发,但是大部分使用的是面向对象开发。 var p0 = Person( 'jim' , 22); print(p0.toString()); var s0 = Student.withMap({ 'name' : 'jack' , 'age' : 18, 'height' : 33.3 }); print(s0); } // 1.类的基本定义 // 类默认是继承自Object的,应用创建的对象是可以使用Object中的方法的。 class Person { String name; int age; // Person(String name, int age) { // this.name = name; // this.age = age; // } // 语法糖 Person( this .name, this .age); } // 2.类的构造函数 class Student { String name; int age; double height; // a.普通的构造方法 Student( this .name, this .age); // b.命名构造函数:因为Dart中不支持函数重载,所以出现了命名构造函数来作为构造函数 Student.withNameAgeHeight( this .name, this .age, this .height); /* dynamic和Object的区别 dynamic是类型声明,var是类型推断,它是一个具体类型的声明,如String。 dynamic是运行时报错 Object是编译时报错 Object可以父类指向子类对象。 Object obj = 'hello'; print(obj.toString(1)); */ Student.withMap(Map<String, dynamic> map) { this .name = map[ 'name' ]; this .age = map[ 'age' ]; this .height = map[ 'height' ]; } // c.重新类的描述方法 @override String toString() { // TODO: implement toString return "$age, $name, $height" ; } } // 3.类的初始化列表 class Teacher { final String name; final int age; /* 构造函数的结构体执行时,是在构造函数执行后,所以对于final属性,它必须在构造函数执行时进行执行 所以此时的执行时间就是在结构体执行时,故:它的执行是在():后面的初始化列表里执行。 初始化列表:里面执行不仅包含编辑期静态返回值,还可以包含动态调用返回值。如:Color.blue 可选命名表达式: 只能有赋值表达式,如:int age = temp ?? 20 */ // Teacher(this.name, {int age = 10, String color}): this.color = color ?? '' { // } Teacher(): this .name = 'jc' , this .age = 10 { } } // 4.构造函数重定向 class Doctor { int age; String name; // 构造函数重定向 Doctor(String name): this ._internal(name, 10); // 命名构造函数 Doctor._internal(String name, int age); } // 5.常量构造函数,相同的属性只有一个内存对象。 class Apple { final String name; final int age; const Apple( this .name, this .age); } // 6.工厂构造函数:最大的特点可以手动返回一个对象。 /* 普通构造函数不需要写return 会自动返回实例对象。 工厂构造函数需要写return 手动返回实例对象。 static:全局静态方法,类方法。 */ class Orange { String name; String color; static final Map<String, Orange> _nameCache = {}; static final Map<String, Orange> _colorCache = {}; factory Orange.withName(String name) { if (_nameCache.containsKey(name)) { return _nameCache[name]; } else { final p = Orange(name, 'red' ); _nameCache[name] = p; return p; } } Orange( this .name, this .color); } // 7.Setter, Getter进行属性监听 // 使用方式是: var e = Elephone(); e.setName('jim'); e.getName class Elephone { String name; // 在Dart中没有private public等修饰符,当对属性_开头时,表示这个属性是私有属性,只能在当前文件模块内访问。 String _age; // setter set setName(String name) { this .name = name; } // getter String get getName { return name; } } // 8.继承:父类的构造函数要在子类的初始化列表中进行调用。 class Animal{ String name; Animal( this .name); void eat() { print( 'eatting' ); } } class Dog extends Animal { int age; // 父类有构造函数时,需要在参数列表中进行调用,初始化。 Dog( this .age, String name): super (name); } // 9.抽象类 // a.子类继承抽象父类,父类的接口方法必须实现,没有option可选项。 // b.抽象类不能实例化 /* c.系统抽象类Map实例化分析 Map是一个抽象类,而可以调用Map()产生实例对象的原因是因为 调用的Map()是Map抽象类的工厂方法external factory Map(); external 是一个方法存在声明,表示此方法已经存在,但不在这里实现。这样实现和声明分离 的好处是,可以在实现的地方使用runtimeType集中处理不同平台逻辑,而通过方法接口声明在不同的平台 调用。 实现的地方使用@patch修饰。 */ abstract class Shape { int getArea(); String getInfo() { return '形状' ; } void testMap() { final m = Map(); print(m.runtimeType); } } class Rectangle extends Shape { @override int getArea() { return 20; } } // 10.dart隐式接口:dart中定义的class同时也可以当接口使用。 /* dart中没有interface/ protocal这样专门定义接口的关键字 dart中定义的class 同时也具有接口的功能,把class当接口使用时,class中定义的方法必须要全部实现。 dart是单继承 */ class Runner { void run() { print( 'running' ); } } class Fly { void fly() { print( 'fly' ); } } class SuperMan extends Animal implements Runner, Fly { SuperMan(String name): super (name); // 1.接口实现 @override void run() { // TODO: implement run } @override void fly() { // TODO: implement fly } // 2.方法重写 @override void eat() { // TODO: implement eat super .eat(); } } // 11.混入mixin /* 混入mixin间接实现多继承,可以同时引入多个mixin类中的方法 dart是单继承, 如果要想同时引入多个mixin类中的方法,则可以定义多个mixin类来引入 定义用mixin 使用用with */ mixin Play { void play() { print( 'play' ); } } mixin Jump { void jump() { print( 'jump' ); } } class Robbit extends Animal with Play, Jump { Robbit(String name): super (name); @override void eat() { // TODO: implement eat super .eat(); } } /* 12.static 类属性,类方法 */ class SuperWoman { // 成员变量,成员方法 var name; void fly() { } // 静态/类变量,静态/类方法 static var flyYear; static void run() { } } |
7.枚举
Dart相比JavaScript增加了枚举类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | void main(List<String> args) { var color = Colors.red; switch (color) { case Colors.blue: print( '蓝色' ); break ; case Colors.red: print( '红色' ); break ; case Colors.yellow: print( '黄色' ); break ; default : }; print(Colors.values); } enum Colors { red, blue, yellow } |
8.库的使用
dart中,一个文件就是一个模块或一个库。
dart中的库有三种:系统库,自定义库,第三方库。
系统库:dart中的Core核心库无需导入,默认导入。如使用的Map
如果使用其他专门功能,就导入专门的库,如:
1 2 3 | import 'dart:async' ; import 'dart:io' ; import 'dart:库的名称' ; |
1 2 3 | import '08_dart_自定义库_utils/math_utils.dart' 如果自定义库和当前模块或系统库方法名重复,可以是as重命名来区分 import '08_dart_自定义库_utils/math_utils.dart' as MathUtils; |
1 | import 'package:http/http.dart' as http; |
1.as关键字可以给库起别名
2.默认情况下,导入一个库时会导入库中的所有内容,此时可以使用修饰词声明部分导入
show: 声明要导入的部分
hide: 声明要隐藏的部分
1 2 3 | import '08_dart_自定义库_utils/math_utils.dart' as MathUtils; import '08_dart_自定义库_utils/math_utils.dart' show sum; import '08_dart_自定义库_utils/math_utils.dart' hide sub ; |
1 2 | export 'io_utils.dart' ; export 'math_utils.dart' ; |
4.库文件中的私有方法是_开头的方法。
5.flutter项目第三方库管理文件pubspec.yaml, 然后执行pub get进行更新。
1 2 3 4 | name: zhoufei description: a dart lib dependencies: http: ^0.12.0 |
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | import 'dart:math' ; import 'dart:convert' as convert; import '08_dart_自定义库_utils/math_utils.dart' as MathUtils; // import '08_dart_自定义库_utils/math_utils.dart' show sum; // import '08_dart_自定义库_utils/math_utils.dart' hide sub ; import 'package:http/http.dart' as http; void main(List<String> args) async { final num1 = 10; final num2 = 20; print(min(num1, num2)); MathUtils.sub(num1, num2); var url = Uri.https( 'www.googleapis.com' , '/books/v1/volumes' , { 'q' : '{http}' }); // Await the http get response, then decode the json-formatted response. var response = await http.get(url); if (response.statusCode == 200) { var jsonResponse = convert.jsonDecode(response.body) as Map<String, dynamic>; var itemCount = jsonResponse[ 'totalItems' ]; print( 'Number of books about http: $itemCount.' ); } else { print( 'Request failed with status: ${response.statusCode}.' ); } } /* dart中,一个文件就是一个模块或一个库 注意: 1.as关键字可以给库起别名 2.默认情况下,导入一个库时会导入库中的所有内容,此时可以使用修饰词声明部分导入 show: 声明要导入的部分 hide: 声明要隐藏的部分 import '08_dart_自定义库_utils/math_utils.dart' as MathUtils; import '08_dart_自定义库_utils/math_utils.dart' show sum; import '08_dart_自定义库_utils/math_utils.dart' hide sub ; 3.export统一导出一类库文件,当一个目下有多个工具库时,可以统一放到一个文件中,集中导入防止每个都导入一次 export 'io_utils.dart'; export 'math_utils.dart'; 4.库文件中的私有方法是_开头的方法。 5.flutter项目第三方库管理文件pubspec.yaml, 然后执行pub get进行更新。 name: zhoufei description: a dart lib dependencies: http: ^0.12.0 系统库 dart中的Core核心库无需导入,默认导入。如使用的Map 如果使用其他专门功能,就导入专门的库,如: import 'dart:async'; import 'dart:io'; import 'dart:库的名称'; 自定义库 导入方式 import '08_dart_自定义库_utils/math_utils.dart' 如果自定义库和当前模块或系统库方法名重复,可以是as重命名来区分 import '08_dart_自定义库_utils/math_utils.dart' as MathUtils; 第三方库 导入方式 import 'package:http/http.dart' as http; */ |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 李飞飞的50美金比肩DeepSeek把CEO忽悠瘸了,倒霉的却是程序员
· 超详细,DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方Dee
· 用 DeepSeek 给对象做个网站,她一定感动坏了
· .NET 8.0 + Linux 香橙派,实现高效的 IoT 数据采集与控制解决方案