歡迎關注微信公眾號:FSA全棧行動 ?
相關程式碼存放於:github.com/LinXunFeng/…
一、變數/常量
明確宣告
// 明確宣告
String name = 'lxf';
int age = 18;
double height = 1.8;
print('$name, $age, $height'); // lxf, 18, 1.8
複製程式碼
型別推導
var
runtimeType
: 用於獲取變數當前的型別
var count = 1; // count的型別為int
print(count.runtimeType); // int
// count = "abc"; // 報錯,無法為int型別賦值一個字串
複製程式碼
dynamic
dynamic
宣告的變數可以賦值為任意型別在開發中一般不這種做,因為會帶來潛在的危險
dynamic type = 'lxf';
print(type.runtimeType); // String
type = 18;
print(type.runtimeType); // int
// type.abc(); // 編譯期不會報錯,執行時找不到方法報錯
複製程式碼
final & const
final
和const
都用來定義變數
final gender = 'male';
// gender = 'female' // 報錯
const country = 'China';
// country = 'USA'; // 報錯
複製程式碼
區別:
const
: 必須賦值,接收一個常量值(即編譯期間就需要確定的值)final
: 可以通過計算/函式動態獲取值(即執行時能確定的值)
String getName() {
return 'lxf';
}
main(List<String> args) {
final myName = getName();
// const myName = getName(); // 報錯
}
複製程式碼
二、資料型別
int
: 整數double
: 浮點數
注:int
和 double
表示的範圍不是固定的,具體取決於執行 Dart
的平臺
整型
// 整型
int age = 18;
int hexAge = 0x12;
print(age); // 18
print(hexAge); // 18
複製程式碼
浮點型
// 浮點型別 double
double height = 1.8;
print(height); // 1.8
複製程式碼
布林型別
var isFlag = true;
print('$isFlag ${isFlag.runtimeType}'); // true bool
複製程式碼
- Dart中沒有非0即真或非空即真
var msg = 'lxf';
if (msg) { // 報錯 Conditions must have a static type of 'bool'.
print(msg);
}
複製程式碼
字串
// 字串
var s1 = 'hello lxf';
var s2 = "hello lxf";
複製程式碼
多行字串
// 多行字串
var s3 = '''
hello
hey
lxf''';
複製程式碼
字串拼接
- 字串和其他變數或表示式拼接: 使用
${expression}
, 如果表示式是一個識別符號, 那麼{}
可以省略
var s4 = s1 + s2;
print(s4); // hello lxfhello lxf
var s5 = 's1 = $s1 and s4 = ${s1 + s2}';
print(s5); // s1 = hello lxf and s4 = hello lxfhello lxf
複製程式碼
三、集合
List
- 使用
[]
字面量
var letters = ['a', 'b', 'c', 'd'];
print('$letters ${letters.runtimeType}'); // [a, b, c, d] List<String>
List<int> numbers = [1, 2, 3, 4];
print('$numbers ${numbers.runtimeType}'); // [1, 2, 3, 4] List<int>
複製程式碼
List
特有的操作
// 由於List的元素是有序的,所有它還提供了一個刪除指定索引位置上元素的方法removeAt
// List根據index刪除元素
numbers.removeAt(3);
print('$numbers'); // [2, 3, 4]
複製程式碼
Set
- 使用
{}
字面量- 與
List
的兩個不同點:Set
是無序的,且元素不重複
var lettersSet = {'a', 'b', 'c', 'd'};
print('$lettersSet ${lettersSet.runtimeType}'); // {a, b, c, d} _CompactLinkedHashSet<String>
Set<int> numbersSet = {1, 2, 3, 4};
print('$numbersSet ${numbersSet.runtimeType}'); // {1, 2, 3, 4} _CompactLinkedHashSet<int>
複製程式碼
Map
var infoMap1 = {'name': 'lxf', 'age': 18};
print('$infoMap1 ${infoMap1.runtimeType}');
// {name: lxf, age: 18} _InternalLinkedHashMap<String, Object>
Map<String, Object> infoMap2 = {'height': 1.8, 'country': 'China'};
print('$infoMap2 ${infoMap2.runtimeType}');
// {height: 1.8, country: China} _InternalLinkedHashMap<String, Object>
複製程式碼
Map
特有的操作
// 1.根據key獲取value
print(infoMap1['name']); // lxf
// 2.獲取所有的entries
print('${infoMap1.entries} ${infoMap1.entries.runtimeType}');
// (MapEntry(name: lxf), MapEntry(age: 18)) MappedIterable<String, MapEntry<String, Object>>
// 3.獲取所有的keys
print('${infoMap1.keys} ${infoMap1.keys.runtimeType}');
// (name, age) _CompactIterable<String>
// 4.獲取所有的values
print('${infoMap1.values} ${infoMap1.values.runtimeType}');
// (lxf, 18) _CompactIterable<Object>
// 5.判斷是否包含某個key或者value
print('${infoMap1.containsKey('age')} ${infoMap1.containsValue(18)}');
// true true
// 6.根據key刪除元素
infoMap1.remove('age');
print('${infoMap1}'); // {name: lxf}
複製程式碼
集合共有的操作
// 長度
print(letters.length); // 4
print(lettersSet.length); // 4
print(infoMap1.length); // 2
// 新增、刪除、包含元素
numbers.add(5);
numbersSet.add(5);
print('$numbers $numbersSet'); // [1, 2, 3, 4, 5] {1, 2, 3, 4, 5}
numbers.remove(1);
numbersSet.remove(1);
print('$numbers $numbersSet'); // [2, 3, 4, 5] {2, 3, 4, 5}
print(numbers.contains(2)); // true
print(numbersSet.contains(2)); // true
複製程式碼
四、函式
函式也是物件,型別為
Function
函式定義
注意點:
Dart
不支援函式過載!(函式過載:函式名稱相同,引數不同)
返回值 函式的名稱(引數列表) {
函式體
return 返回值
}
複製程式碼
普通函式
num sum1(num num1, num num2) {
return num1 + num2;
}
print(sum1(1, 2)); // 3
複製程式碼
省略了型別註釋也可以正常工作,但是不建議這麼做
sum2(num1, num2) {
return num1 + num2;
}
print(sum2(1, 2)); // 3
複製程式碼
如果函式的實現只有一個表示式,則可以使用箭頭語法
sum3(num num1, num num2) => num1 + num2;
print(sum3(1, 2)); // 3
複製程式碼
可選引數
命名可選引數
定義:命名可選引數:
{param1, param2, ...}
注意:
- 如果確定傳入的引數不能為
null
,則需要加required
關鍵字- 如果傳入的引數可能為
null
,則引數型別後面需要加?
// 命名可選引數
printInfo1(String name, {int? age, double? height}) {
print('name = $name age = $age height = $height');
}
// 確定引數不能為null,需要新增 required 關鍵字
// printInfo1(String name, {required int age, required double height}) {}
複製程式碼
引數預設值
printInfo3(String name, {int age = 18, double height = 1.8}) {
print('name = $name age = $age height = $height');
}
複製程式碼
呼叫
// 命名可選引數
printInfo1('lxf'); // name = lxf age = null height = null
printInfo1('lxf', age: 18); // name = lxf age = 18 height = null
printInfo1('lxf', age: 18, height: 1.8); // name = lxf age = 18 height = 1.8
printInfo1('lxf', height: 1.8); // name = lxf age = null height = 1.8
// 引數預設值
printInfo3('lxf'); // name = lxf age = 18 height = 1.8
複製程式碼
位置可選引數
- 定義:位置可選引數:
[param1, param2, ...]
- 注意:位置可選引數無法使用
required
關鍵字
// 位置可選引數
printInfo2(String name, [int? age, double? height]) {
print('name = $name age = $age height = $height');
}
複製程式碼
引數預設值
printInfo4(String name, [int age = 18, double height = 1.8]) {
print('name = $name age = $age height = $height');
}
複製程式碼
呼叫
// 位置可選引數
printInfo2('lxf'); // name = lxf age = null height = null
printInfo2('lxf', 18); // name = lxf age = 18 height = null
printInfo2('lxf', 18, 1.8); // name = lxf age = 18 height = 1.8
// 引數預設值
printInfo4('lxf'); // name = lxf age = 18 height = 1.8
複製程式碼
五、運算子
常見的運算子
var num = 10;
print(num / 3); // 除法:3.3333333333333335
print(num ~/ 3); // 整除:3
print(num % 3); // 取模:1
複製程式碼
賦值運算子
??=
: 當變數為null
時,使用後面的內容進行賦值
// 賦值運算子
var name = null;
name ??= 'lxf';
print(name); // lxf
var name1 = 'lin';
name1 ??= 'lxf';
print(name1); // lin
複製程式碼
條件運算子
??
: 當變數為null
時,則使用後面的值,否則使用變數的值
var temp = null;
var other = temp ?? 'lxf';
print(other); // lxf
複製程式碼
級聯
..
: 可以對物件進行連續操作
class Person {
String name;
Person(this.name);
void run() {
print("$name is running");
}
void eat() {
print('$name is eating');
}
void swim() {
print('$name is swimming');
}
}
main(List<String> args) {
final p1 = Person('lxf');
p1.run();
p1.eat();
p1.swim();
final p2 = Person('lin')
..run()
..eat()
..swim();
}
複製程式碼
六、流程控制
if
和 else
不支援非空即真或非0即真,必須是明確的
bool
型別
var isHot = true;
if (isHot) {
print('熱門');
} else {
print('冷門');
}
複製程式碼
for
// for
for (var i = 0; i < 10; i++) {
print(i);
}
// for in 遍歷集合
var names = ['lxf', 'lin'];
for (var name in names) {
print(name);
}
複製程式碼
while
var index = 0;
while (index < 5) {
print('index -- $index');
index++;
}
複製程式碼
do-while
var index = 0;
do {
print('index -- $index');
index++;
} while (index < 10);
複製程式碼
break
- 退出迴圈
var i = 1;
while (i <= 10) {
if (i % 5 == 0) {
print("滿足條件,退出迴圈");
break;
}
// 繼續下一個迴圈
i++;
}
複製程式碼
continue
- 終止當前迭代並開始後續迭代
- 不會退出迴圈
var num = 0;
var count = 0;
for (num = 0; num <= 20; num++) {
if (num % 2 == 0) {
continue;
}
count++;
}
print("累加次數: $count"); // 累加次數: 10
複製程式碼
switch-case
var direction = 'east';
switch (direction) {
case 'east':
print('東面');
break;
case 'south':
print('南面');
break;
case 'west':
print('西面');
break;
case 'north':
print('北面');
break;
default:
print('其他方向');
}
複製程式碼
六、類
類的定義如下:
class 類名 {
型別 成員名;
返回值型別 方法名(引數列表) {
方法體
}
}
複製程式碼
late
關鍵字
作用:顯式宣告一個非空的變數,但不初始化,延遲變數的初始化
預設的建構函式是無參構建函式,這意味著屬性無法從預設構建函式得到初始化,這時有兩個選擇,
選擇一:自定義一個建構函式對屬性進行初始化
選擇二:使用 late
關鍵字修飾屬性,延遲變數的初始化
加上 late
關鍵字可以通過靜態檢查,但是會帶來執行時風險,你需要保證屬性在使用前有進行初始化!
class Person {
late String name;
late int age;
}
main(List<String> args) {
var p1 = Person();
p1.name = 'lxf';
print(p1.name); // lxf
print(p1.age); // 報錯:LateInitializationError: Field 'age' has not been initialized.
}
複製程式碼
構造方法
普通構造方法
當類中沒有指定構造方法時,預設會有一個無參的構造方法
class Person {
String? name;
int? age;
}
main(List<String> args) {
var p1 = Person(); // 預設的構造方法
}
複製程式碼
可以根據自已的需求,定義自已的構建方法,不過需要注意的是:
當定義了自已的構建方法,則預設的無參構造方法會失效,無法使用!
class Person {
String name;
int age;
Person(this.name, this.age);
}
複製程式碼
命名構造方法
由於 Dart
不支援方法過載,所以沒辦法建立相同名稱的構造方法,如果希望能實現更多的構造方法,這時就需要使用命名構造方法
class Person {
String? name;
int? age;
Person.withArgs(String name, int age) {
this.name = name;
this.age = age;
}
}
main(List<String> args) {
// var p1 = Person(); // 預設構造方法失效
var p1 = Person.withArgs('lxf', 18);
print(p1.name);
print(p1.age);
}
複製程式碼
重定向構造方法
在一個構造方法中,呼叫另一個構造方法進行初始化
class Person {
String name;
int age;
Person(this.name, this.age);
// 重定向構造方法
Person.from(String name): this(name, 0);
}
複製程式碼
常量構造方法
使用
const
修飾構造方法,當傳入相同引數時,可以確保建立出來的物件是相同的注意點:
- 擁有常量構造方法的類中,所有的成員變數必須是final修飾的
- 為了建立出相同的物件,在使用常量構造方法時,需要使用
const
關鍵字
class Person {
// 擁有常量構造方法的類中,所有的成員變數必須是final修飾的
final String name;
const Person(this.name);
}
main(List<String> args) {
var p1 = const Person('lxf');
var p2 = const Person('lxf');
var p3 = const Person('lxf1');
const p4 = Person4('lxf');
// 判斷是不是同一個物件
print(identical(p1, p2)); // true
print(identical(p1, p3)); // false
print(identical(p1, p4)); // true
}
複製程式碼
工廠構造方法
class Person {
late String name;
static final Map<String, Person> _cache = <String, Person>{};
// 工廠構造方法
factory Person(String name) {
var p = _cache[name];
if (p == null) {
p = Person._internal(name);
_cache[name] = p;
}
return p;
}
Person._internal(this.name);
}
main(List<String> args) {
var p1 = Person5('lxf');
var p2 = Person5('lxf');
// 判斷是不是同一個物件
print(identical(p1, p2)); // true
}
複製程式碼
注意:當工廠構造方法與預設構造方法重名時,無法被繼承,會報錯
The default constructor of superclass 'Father' (called by the implicit default constructor of 'Son') must be a generative constructor, but factory found.
父類的構造器必須是一個生成的構造器,而不能是工廠構造器
複製程式碼
如下方程式碼所示
class Father {
factory Father() {
return Father._internal();
}
Father._internal();
}
class Son extends Father {} // 編譯報錯
複製程式碼
需要新增一個生成構造器,並將工廠構造器改為命名構造器
class Father {
Father();
factory Father.factory() {
return Father._internal();
}
Father._internal();
}
class Son extends Father {}
複製程式碼
getter
和 setter
當希望類中定義的屬性不輕易給外部訪問時,就可以用到
getter
和setter
class Marker {
String _color;
String get color => _color;
set color(String color) {
_color = color;
}
Marker(this._color);
}
main(List<String> args) {
final m = Marker('red');
m.color = 'blue';
print(m.color); // blue
}
複製程式碼
繼承
繼承使用
extends
關鍵字,子類中使用super
來訪問父類
class Animal {
String name;
Animal(this.name);
eat() {
print("吃吃吃");
}
}
class Dog extends Animal {
Dog(String name) : super(name);
}
main(List<String> args) {
var dog = Dog("Spike");
dog.eat(); // 吃吃吃
print(dog.name); // Spike
}
複製程式碼
重寫父類的方法,@override
是註釋,用來標明當前為重寫的方法,可有可無,但一般保留著
class Dog extends Animal {
Dog(String name) : super(name);
// 重寫父類的eat方法
@override
eat() {
print("$name 在吃");
}
}
複製程式碼
抽象類
抽象類:使用
abstract
宣告的類,用於定義通用介面,無法被例項化,方法可以沒有實現,該方法稱為抽象方法,交由子類去實現
abstract class Building {
getHeight();
getArea() {
print("hello");
}
}
class Tower extends Building {
@override
getHeight() {
print("55m");
}
}
main(List<String> args) {
var tower = Tower();
tower.getArea(); // hello
tower.getHeight(); // 55m
}
複製程式碼
隱式介面
-
Dart
沒有關鍵字可以用來宣告介面,所有的類都是隱式介面 -
當一個類被當作介面使用時,那麼實現這個介面的類必須實現介面中的所有方法
-
實現介面使用
implements
關鍵字 -
被實現的介面方法不可以使用
super
呼叫介面中的方法
class Runner {
run() {
print("running");
}
}
abstract class Fly {
fly();
}
class SuperPerson implements Runner, Fly {
@override
run() {
// 實現介面的方法不可以呼叫super
// 報錯:The method 'run' is always abstract in the supertype.
// super.run();
print('自由自在的奔跑');
}
@override
fly() {
print('起飛');
}
}
複製程式碼
Mixin混入
Dart
不支援多繼承,使用介面時需要實現介面中的所有方法,而我們需要在當前類可以複用其它類中的實現時就需要用到 Mixin混入
的方式。
- 定義:To implement a mixin, create a class that extends Object and declares no constructors. Unless you want your mixin to be usable as a regular class, use the mixin keyword instead of class.
- 取自官方連結:dart.dev/guides/lang…
- 大致意思:建立一個繼承自
Object
的類,且沒有宣告建構函式,則該類就可被混入。除非你希望你的混入類可以被當作常規類使用,否則請使用mixin
關鍵字,而不是class
特性:
-
mixin
關鍵字宣告混入(非必要,也可以用class
) -
混入類繼承自
Object
,且不可以有構造方法 -
on
關鍵字限定指定類的子類可以使用當前混入(不加預設限定為Object
) -
使用
mixin
後無法被繼承 -
使用
with
進行混入 -
父類與混入的方法重名時,使用的是混入的方法
// mixin Runner {} // 可以不使用on,預設是 on Object
mixin Runner on Animal {
run() {
print('跑起來了');
}
}
class Animal {
run() {
print('Animal run');
}
}
class SuperPeople extends Animal with Runner {} // 必須繼承 Animal 才可以混入 Runner
// 報錯:'Runner' can't be mixed onto 'Object' because 'Object' doesn't implement 'Animal'.
// class Person with Runner {}
// 報錯:Classes can only extend other classes.
// class Person extends Runner {} // Runner無法被繼承
main(List<String> args) {
var p = SuperPeople();
p.run(); // 跑起來了(使用的是混入的方法,而不是父類中的)
}
複製程式碼
當前類、父類與混入的實現優先順序
總結:當前類 > 混入 > 父類
class A {
void method() {
print('I am A');
}
}
class B {
void method() {
print('I am B');
}
}
class C extends A with B {
// void method() {
// print('I am C');
// }
}
main(List<String> args) {
var c = C();
/**
* C 有無自己的 method 方法實現:
* - 有:列印:I am C
* - 無:列印:I am B
*/
c.method();
}
複製程式碼
七、列舉
// 定義列舉
enum Color { red, blue, green }
main(List<String> args) {
print(Color.red); // Color.red
print(Color.red.index); // 0 列舉的下標從0開始
print(Color.blue.index); // 1
print(Color.values); // [Color.red, Color.blue, Color.green]
var color = Color.green;
switch (color) {
case Color.red:
print("紅");
break;
case Color.blue:
print("藍");
break;
case Color.green:
print("綠");
break;
}
}
複製程式碼
八、泛型
List
使用泛型
// List
var myList = ['lxf', 18];
print(myList.runtimeType); // List<Object>
// List使用泛型,限制型別
var numList = <int>[10, 20];
List<String> nameList = ["lxf", "lin"]; // 一般使用這種
// 報錯: The element type 'int' can't be assigned to the list type 'String'.
// List<String> nameList = ["lxf", "lin", 18];
複製程式碼
Map
使用泛型
// Map
var msgMap = {1: 'one', 'name': 'lxf', 'age': 18};
print(msgMap.runtimeType); // _InternalLinkedHashMap<Object, Object>
// Map使用泛型,限制型別
var infoMap = <String, String>{'name': 'lxf', 'age': '18'};
// Map<String, String> profileMap = {'name': 'lxf', 'age': '18'}; // 一般使用這種
// 報錯:The element type 'int' can't be assigned to the map value type 'String'.
// Map<String, String> profileMap = {'name': 'lxf', 'age': 18};
複製程式碼
類定義泛型
將類的屬性以泛型做為型別宣告,由外部來決定最終的型別
class Point<T> {
T x;
T y;
Point(this.x, this.y);
}
main(List<String> args) {
Point p = Point<double>(10.5, 20.5);
print(p.x.runtimeType); // double
}
複製程式碼
如果希望屬性的型別只能是數字,可以使用 extends
來限制泛型 T
只能為 num
的子類
class Size<T extends num> {
T width;
T height;
Size(this.width, this.height);
}
main(List<String> args) {
Size s = Size<int>(20, 10);
// 報錯:A value of type 'Size<String>' can't be assigned to a variable of type 'Size<num>'.
// Size s1 = Size<String>("20", "10");
}
複製程式碼
九、庫的使用
庫的匯入
Dart
標準庫
Dart
標準庫的匯入字首為dart:
import 'dart:io';
import 'dart:html';
import 'dart:math';
複製程式碼
自定義庫
libs/math_utils.dart
檔案的內容:
num sum(num num1, num num2) {
return num1 + num2;
}
num multiply(num num1, num num2) {
return num1 * num2;
}
複製程式碼
使用
// 匯入自定義庫
import 'libs/math_utils.dart';
main(List<String> args) {
print(sum(10, 20)); // 30
print(multiply(10, 20)); // 200
}
複製程式碼
第三方庫
在專案目錄下建立 pubspec.yaml
檔案,在 dependencies
下新增需要依賴的第三方的庫名與版本
第三庫的使用說明可在 pub.flutter-io.cn 上查詢
name: dartStudy
description: this is lxf's study project
dependencies:
dio: ^4.0.0
environment:
sdk: ">=2.10.0 <3.0.0"
複製程式碼
填寫好依賴後,在終端下執行 dart pub get
命令,終端會自動拉取對應版本的第三方檔案,之後在程式碼中就可以匯入並使用
// 匯入第三方庫
import 'package:dio/dio.dart';
main(List<String> args) {
getHttp();
}
void getHttp() async {
try {
var response = await Dio().get('http://www.google.cn');
print(response);
} catch (e) {
print(e);
}
}
複製程式碼
延遲載入
- 作用:在需要的時候才進行載入
- 好處:減少
App
的啟動時間- 使用:使用
deferred as
// 延遲載入
import 'package:dio/dio.dart' deferred as diolib;
複製程式碼
在使用延遲載入的庫中,需要呼叫 loadLibrary
以載入宣告為延遲載入的庫
main(List<String> args) async {
// 呼叫loadLibrary方法來載入延遲載入的庫
await diolib.loadLibrary();
diolib.Dio().get('http://www.google.cn');
}
複製程式碼
給庫起別名
一般在與別的庫的內容衝突時使用
import 'libs/math_utils.dart' as MathUtils; // 別名
main(List<String> args) {
print(MathUtils.sum(10, 20)); // 30
print(MathUtils.multiply(10, 20)); // 200
}
複製程式碼
指定庫內容的顯示與隱藏
import 'libs/math_utils.dart' show sum, multiply; // show: 顯示指定的內容(即部分引入)
import 'libs/math_utils.dart' hide sum; // hide: 隱藏指定的內容
複製程式碼
library
、part
和 part of
作用:
library
:定義庫名
part
:關聯分庫檔案
part of
:宣告隸屬哪個庫,使用的是library
定義的庫名特點:
library
、part
和part of
都必須定義在檔案的第一行,否則會報錯- 主庫可以訪問分庫中的私有成員
- 如果需要匯入其它庫,只能在主庫中匯入,無法在分庫中匯入,且
import
只能放在library
和part
之間- 如果外部需要使用到分庫的內容,只需要匯入主庫即可
檔案目錄結構:
├── 16_庫的定義.dart
└── lib
└── part
├── fitsize.dart
├── fitsize_part1.dart
└── fitsize_part2.dart
複製程式碼
fitsize.dart
檔案內容
// 定義庫名
library fitsize;
// 關聯分庫
part 'fitsize_part1.dart';
part 'fitsize_part2.dart';
void fit() {
// 可以訪問分庫下的私有成員
part1PublicMethod(); // part1 public method
_part1PrivateMethod(); // part1 private method
part2PublicMethod(); // part2 public method
_part2PrivateMethod(); // part2 private method
}
複製程式碼
fitsize_part1.dart
檔案內容
part of fitsize; // 宣告為主庫的一部分
part1PublicMethod() {
print("part1 public method");
}
_part1PrivateMethod() {
print("part1 private method");
}
複製程式碼
fitsize_part2.dart
檔案內容
part of fitsize; // 宣告為主庫的一部分
part2PublicMethod() {
print("part2 public method");
}
_part2PrivateMethod() {
print("part2 private method");
}
複製程式碼
這樣三個 dart
檔案就組成了 fitsize
庫,如果外部需要使用到分庫的內容,只需要匯入主庫即可。
如果需要匯入其它庫,只能在主庫中匯入,無法在分庫中匯入,且 import
只能放在 library
和 part
之間,否則會報錯。
// fitsize.dart 主庫檔案
// 定義庫名
library fitsize;
import 'dart:io'; // 匯入其它庫,只能放在這個位置
// 關聯分庫
part 'fitsize_part1.dart';
part 'fitsize_part2.dart';
複製程式碼
export
官方不再推薦使用
part
關鍵字,而是推薦使用export
- 使用:在一個
dart
檔案裡使用export
關鍵字,將其它庫檔案匯出- 作用:這樣外部在使用時只需要匯入一個檔案即可使用完整的庫內容
檔案目錄結構:
├── 16_庫的定義.dart
└── lib
└── export
├── lxf_utils.dart
└── source
├── lxf_file_util.dart
└── lxf_math_util.dart
複製程式碼
lxf_utils.dart
檔案內容:
// 定義庫名
library lxf_utils;
// 匯出所有的庫
export './source/lxf_math_util.dart';
export './source/lxf_file_util.dart';
複製程式碼
lxf_math_util.dart
檔案內容:
num sum(num num1, num num2) {
return num1 + num2;
}
複製程式碼
lxf_file_util.dart
檔案內容:
writeFile(String name, String dir_path) {
print('寫入檔案 $dir_path$name ');
}
複製程式碼
匯入並呼叫
import 'lib/export/lxf_utils.dart' as utils;
main(List<String> args) {
print(utils.sum(1, 2)); // 3
utils.writeFile('lxf.jpg', '/lxf/Desktop/'); // 寫入檔案 /lxf/Desktop/lxf.jpg
}
複製程式碼