Dart 基础-基础语法

Dart 基础-基础语法

由于学习Flutter的时候不可避免的会使用到Dart语言,Dart语言也因此显得格外重要。 一直想总结一篇语法基础作为备忘, 今天终于实现这么目标了。 尽管是个小目标。

这一篇文章总结一点Dart语法基础

开发环境的配置不作为本文的重点进行讨论。

本文是基于的dart sdk 是stable 2.4.0, devel 2.5.0-dev.1.0

由于笔者主要使用的语言是Java,文中大部分语法会和Java类比

主要分以下几个部分展开记录

  • 1.变量
  • 2.函数
  • 3.操作符和流程控制语句
  • 4.类和对象
  • 5.容器
  • 6.库的引用
  • 7.总结
  • 8.参考资料

1. 变量

import 'dart:mirrors';

main(List<String> arguments) {

  //Dart 语言本质上是动态类型语言,类型是可选的
  //可以使用 var 声明变量,也可以使用类型来声明变量
  //一个变量也可以被赋予不同类型的对象
  
  var test;

  test = 'type-test';
  //  结果 String
  print(reflect(test).type.reflectedType);
  /// 之前的版本 不支持 + 操作符  结果  type-testtype-test
  print(test+test)  
  /// 改变类型 
  test= 27;
   int 
  print(reflect(test).type.reflectedType);
  ///  54
  print(test+test); 
 
  //但大多数情况,我们不会去改变一个变量的类型 
  
  //字符串赋值的时候,可以使用单引号,也可以使用双引号
  var str1 = "Ok?";
  
  //如果使用的是双引号,可以内嵌单引号
  //当然,如果使用的是单引号,可以内嵌双引号,否则需要“\”转义
  //String str2 = ‘It\’s ok!’;
  String str2 = "It's ok!";
  
  //使用三个单引号或者双引号可以多行字符串赋值
  var str3 = """Dart Lang
  Hello,World!""";
  
  //在Dart中,相邻的字符串在编译的时候会自动连接
  //这里发现一个问题,如果多个字符串相邻,中间的字符串不能为空,否则报错
  //但是如果单引号和双引号相邻,即使是空值也不会报错,但相信没有人这么做
  //var name = 'Wang''''Jianfei'; 报错
  var name = 'Wang'' ''Jianfei';
  
  //assert 是语言内置的断言函数,仅在检查模式下有效
  //如果断言失败则程序立刻终止
  assert(name == "Wang Jianfei");
  
  //Dart中字符串不支持“+”操作符,如str1 + str2
  //如果要链接字符串,除了上面诉说,相邻字符串自动连接外
  //还可以使用“$”插入变量的值
  print("Name:$name");
  
  //声明原始字符串,直接在字符串前加字符“r”
  //可以避免“\”的转义作用,在正则表达式里特别有用
  print(r"换行符:\n");
  
  //Dart中数值是num,它有两个子类型:int 和 double
  //int是任意长度的整数,double是双精度浮点数

  var hex = 0xF0F;

  //翻了半天的文档,才找打一个重要的函数:转换进制
  //上面提到的字符串插值,还可以插入表达式:${}
  print("整型转换为16进制:$hex —> 0x${hex.toRadixString(16).toUpperCase()}");
  ///  整型转换为16进制:3855 —> 0xF0F 
}

const 和 final 用法和其他语言类似

当然这是使用const 和final 同时,使用这俩可以省略 var 或者其他类型

const 和 final 定义的都是常量,值不能改变
并且在声明的时候就必须初始化
但是有细微差别

  final  time = new DateTime.now();
    print  2018-12-12 16:54:50.904585
  
  const  time = new DateTime.now();
   /// Error   编译不通过  ,  不是 const 常量  
   
  const  time = 'xxx';
  /// xxx 
  print(time);

简单来说,

var、final等在左边定义变量的时候,并不关心右边是不是常量 但是如果右边用了const,那么不管左边如何,右边都必须是常量

2. 函数

(1) 定义

print(funcHello("mick"));
    
// assert(funcHello is Function);
// is  和 !is  
assert(funcHello("jack") is String);

 返回类型 这东西是可以省略的, 但是一般还是留着吧,方便  funcHello() 
String  funcHello(String name){
  return 'Hello '+name;
}

/// 还可以省略成一个表达式 => 
funcHello(name) => 'Hello $name!';

还可以省略成匿名函数

var  funcHello = (name)=>'Hello $name!';

(2) 别名

当看到用typedef定义函数别名的时候,不自觉的想到了C中的函数指针

//  定义别名 add  
typedef String add(int a, int b);
 简写
int subtract(int a, int b) => a - b;

void  main(){

/  结果  true
  print(subtract is Function);
 结果    false  
  print(subtract is add);

}

如果把 add 返回值类型改成 int 则 is 返回 true

(3) 函数闭包

初始化变量的时候,参数对应的是函数的参数num num1
调用函数类型变量的时候,
参数对应的是返回值中的参数num2

var funcName = makeSubstract(5);
print(funcName(2));

Function makeSubstract(num num1){
    return (num num2) => num1 - num2;
}

Dart 中函数也是对象

//  这里边放的是函数指针
  var callbacks = [];
  for (var i = 0; i < 3; i++) {
// 在列表 callbacks 中添加一个函数对象,这个函数会记住 for 循环中当前 i 的值。
    callbacks.add(() => print('Save $i'));
  }

  callbacks.forEach((subFunc) => subFunc());
  // 分别调用子项Function类型的子item 输出 0 1 2


(4) 可选参数

Dart中支持两种可选参数:
命名可选参数和位置可选参数

但两种可选不能同时使用

命名可选参数使用大括号{},默认值用冒号:
位置可选参数使用方括号[],默认值用等号=

///
///在命名可选参数的函数中,大括号外的a为必填参数
///大括号内的参数可以指定0个或多个
//并且与顺序无关,在调用函数的时候需要指明参数名
//没有赋值的参数值为null

funX(a, {b, c:3, d:4, e})
{
  print('$a $b $c $d $e');
}



/
///在位置可选参数的函数中,大括号内的参数可以指定0个
或多个在调用的时候参数值会依次按顺序赋值


funY(a, [b, c=3, d=4, e])
{
  print('$a $b $c $d $e');
}

打印结果:

1 3 3 5 null
1 3 5 4 null

3. 操作符和流程控制语句

这一部分不打算写太多, 因为Dart里面大多内容和Java C++ 没什么区别 , 只总结一下需要注意的地方

(1).取整

取整符号~/ 举个栗子

  var num1 = 3.5;

  var num2 = 1.5;
  
  /// var num2 = 1.2;

  print(num1 / num2);
  
  print(num1 ~/ num2);


打印结果 :

2.3333333333333335
2

调整参数值之后 发现这符号的取整 和Java 中的Math.floor 向下取整 。 总觉得这东西怪怪的 有木有 ~~

(2).对象的级联

当你要对一个单一的对象进行一系列的操作的时候
可以使用级联操作符 …

class Person {
    String name;
    String country;
    void setCountry(String country){
      this.country = country;
    }
    String toString() => 'Name:$name\nCountry:$country';
}
void main() {
  Person p = new Person();
  p ..name = 'Wang'
    ..setCountry('China');
  print(p);
  
  
}

这里的… 就是对单一对象Person p 的操作 不再赘述

(3). if语句


if(3>2){
  print("a");
}else {
  print("b");
}

打印结果 当然是 a ,
至于有的书上写的 if(1) ,我试了几次 编译报错
还有

if(!null){
  print("a");
}else {
  print("b");
}

这个编译不报错, 执行报错

Unhandled exception:
Failed assertion: boolean expression must not be null

算了 还是老老实实传bool值吧

当然还有三目运算符

int age = 60;
String status = age < 50 ? "AAAA" : "BBBB";

(4).循环语句

var sum =0;

for(int i = 1; i<=100; i++) {

    sum +=i;
}

print(sum);

打印结果 5050

增强for 循环

如果迭代的对象是容器,那么可以使用forEach或者for-in

var collection = [0, 1, 2];  这里可以装anything  , 例如上边我们装了 function  

collection.forEach((x) =>print(x));//forEach的参数为Function

for(var x in collection) {
  print(x);
}

还有 while 和do—while 没什么变化 就不再赘述了 。

(5). switch 语句

这里的switch参数可以是 num 也可以是string ,基本用法和Java一样 就不再写了。

这里有一点要注意,如果分句的内容为空,想要fall-through(落空),可以省略break
如果分句的内容不为空,那么必须加break,否则抛出异常

var command = 'OPEN';
switch (command) {
  case 'CLOSED':
    print('CLOSED');
    break;
  case 'OPEN'://产生落空效果,执行下一分句
  case 'NOW_OPEN':
    print('OPEN');
    break;
  default:
    print('Default');
}

如果你想要fall-through,case语句内容又不为空
而又不是按顺序落空,那么可以使用continue和标签

var command = 'CLOSED';
  switch (command) {
    case 'CLOSED':
      print('CLOSED');
      continue nowClosed; // Continues executing at the nowClosed label.
    case 'OPEN':
      print('OPEN');
      break;
    nowClosed: // Runs for both CLOSED and NOW_CLOSED.   直接从'closed’跳转至前边的标记符 nowClosed 继续执行 。 
    case 'NOW_CLOSED':
      print('NOW_CLOSED');
      break;
  }

(6).异常处理

在Java中我们知道所有抛出的异常根据异常的类型不同,但同时是Exception的子类, 当然Exception 继承自 Throwable 。

在Dart中可以抛出非空对象, 也就是说 不仅仅是 Exception 或 Error

throw new ExpectException('分母不能为0!');
throw '分母不能为0!';

你可以抛出多个类型的Exception,但是由第一个catch到的分句来处理
如果catch分句没有指定类型,那么它可以处理任何类型的异常

try {
      throw 'This a Exception!';
  } on Exception catch(e) {
    print('Unknown exception: $e');
  } catch(e) {
    print('Unknown type: $e');
  }

当然也有finally , 用法和Java没有什么区别。

try {
      throw 'This a Exception!';
  } catch(e) {//可以试试删除catch语句,只用try...finally是什么效果
    print('Catch Exception: $e');
  } finally {
    print('Close');
  }

当然 如果把catch 去掉会抛出 Unhandled exception:

4. 类和对象

Dart是一门使用类和单继承的面向对象语言
所有的对象都是类的实例,并且所有的类都是Object的子类

(1).定义

定义和java没什么区别 关键字 class

如果未显式定义构造函数,会默认一个空的构造函数 使用new关键字和构造函数来创建对象

class Point {
  num x;
  num y;
  num z;
}

void main() {
  var point = new Point();
  print(point.hashCode);//未定义父类的时候,默认继承自Object 
  /// 打印结果 991467768 对象的hashCode
}

(2).构造函数

如果只是简单的参数传递,可以在构造函数的参数前加this关键字定义
或者参数后加 : 再赋值

class Point {
    num x;
    num y;
    num z;
    
    Point(this.x, this.y, z) { //第一个值传递给this.x,第二个值传递给this.y
            this.z = z;
    }
    
    Point.fromeList(var list): //命名构造函数,格式为Class.name(var param)
            x = list[0], y = list[1], z = list[2]{//使用冒号初始化变量
    }

    //当然,上面句你也可以简写为:
    //Point.fromeList(var list):this(list[0], list[1], list[2]);
    
     String toString() => 'x:$x  y:$y  z:$z';
}

void main() {
    var p1 = new Point(1, 2, 3);
    var p2 = new Point.fromeList([1, 2, 3]);
    print(p1);//默认调用toString()函数
}

还可以创建一个不可变对象 定义编译时常量对象
需要在构造函数前加const 来个例子


void  main(){

  var immutablePoint = ImmutablePoint.origin;

  var immutablePoint2 = new ImmutablePoint(0, 0);

  print(immutablePoint.hashCode);
  print(immutablePoint2.hashCode);

  print(immutablePoint.toString());

}


class Point {
  num x;
  num y;
  num z;
}


class ImmutablePoint {
  final num x;
  final num y;

  const ImmutablePoint(this.x, this.y);

  // 常量构造函数
  static final ImmutablePoint origin = const ImmutablePoint(0, 0);
// 创建一个常量对象不能用new,要用const
}

打印结果:

903836066
177869238
Instance of 'ImmutablePoint'

(3).Getters And Setters

在Java 中为了保证字段的属性的私有 , Getter和Setter是用来读写一个对象属性的方法, 如果不声明如果具体某个字段的属性是私有的则对外不可访问。

在Dart中 每个字段都对应一个隐式的Getter和Setter

class Rectangle {
  num left;
  num top;
  num width;
  num height;

  Rectangle(this.left, this.top, this.width, this.height);

  // right 和 bottom 两个属性的计算方法
  num get right{
    return left + width;
  }
 这个是单独声明的一个 getright()方法 不要和上边的get right 混淆了  
  num getright(){
    return this.left+ this.width;
  }

  set right(num value) {
    left = value - width;
  }

  // 这是简写不要奇怪  因为没有参数 所有 get  bottom后边的() 也省掉了
  num get bottom => top + height;
  set bottom(num value) => top = value - height;

}

void main(){

  var rect = new Rectangle(3, 4, 20, 15);
  
  print(rect.left);

  rect.right = 12;
  print(rect.left);
  
  print(rect.getright());
  
}

上边的语法可以看出 如果像Java中的getXxx() , setXxx() 的话是访问不到的 ,其访问方式类似于Java中字段访问修饰符为public的时候 。
至于孰优孰劣 看不出来 各有所爱吧, 我还是喜欢Java中的访问方式。 至少可以使用插件自动生成 ~~~
打印结果:

3
-8
12

(4).抽象类和实现

关键字和Java一样 , implements 和 extends
在Dart中类和接口是统一的,类就是接口
如果想重写部分功能,那么可以继承一个类
如果想实现某些功能,那么也可以实现一个类

使用abstract关键字来定义抽象类,并且抽象类不能被实例化
抽象方法不需要关键字,直接以分号 ; 结束即可

abstract class Person {  //此时abstract关键字可加可不加,如果加上的话Person不能被实例化 
    String greet(who); //函数可以没有实现语句,名曰隐式接口,前面不用加 abstract 关键字 
}

当使用 implements的时候,子类Student无法访问父类Person的参数
所以变量name放到了Student
如果生成了一个Student的实例,调用了某函数,那么Student中必须有那个函数的实现语句,无论Person是否实现


class Student implements Person {
  String name;
  Student(this.name);

  String greet(who) => 'Student: I am $name!';
}

class Teacher implements Person {
  String name;
  Teacher(this.name);

  String greet(who) => 'Teacher: I am $name!';
}

void  main(){

  Person student = new Student('Jack');
  Person teacher = new Teacher('Rose');

  print( student.greet('Chen'));
  print(teacher.greet('Chen'));

}

打印结果:

Student: I am Jack!
Teacher: I am Rose!

是不是和Java很像。

可以试一下把Person前的abstract关键字去掉
然后添加构造函数和方法,对Student和Teacher没有影响
但那样的话Student和Teacher的name变量仍然不能省略,那样感觉就冗余了
根据您自己的情况修改吧!
总之,implements可以是实现多个类的多个函数

相比之下继承就好理解得多
Dart中是单继承,子类可以继承父类的非私有变量
当重写某个函数的时候
不用考虑abstract或者接口或者函数实现
直接重写,比如greet()函数
而且仍然保持多态性

class Person { 
  String name; 
    添加构造函数  
  Person(this.name); 
  String greet(who) => 'I am $name!'; 
} 

class Student extends Person {   
  Student(String name):super(name); 
  String greet(who) => 'Student: I am $name!'; 
} 

class Teacher extends Person { 
  Teacher(String name):super(name);  调用父类构造函数  
     String greet(who) => 'Teacher: I am $name!'; 
} 

void main() { 
   Person p1 = new Student('Wang'); 
   Person p2 = new Teacher('Lee'); 
    
   print(p1.greet('Chen')); 
   print(p2.greet('Chen')); 
}

打印结果:

Student: I am Samuel!
Teacher: I am notes!

再来个例子

abstract class Shape {
  // 定义了一个 Shape 类/接口
  num perimeter();
// 这是一个抽象方法,不需要abstract关键字,是隐式接口的一部分。
}

class Rectangle implements Shape {
  // Rectangle 实现了 Shape 接口
  final num height, width;

  Rectangle(num this.height, num this.width);

  // 紧凑的构造函数语法
  num perimeter() => 2 * height + 2 * width;
// 实现了 Shape 接口要求的 perimeter 方法
}

class Square extends Rectangle {
  // Square 继承 Rectangle
  Square(num size) : super(size, size);
// 调用超类的构造函数
}

void main(){
    Shape rectangle = new Rectangle(100,200);
    Shape square = new Square(100);

    print(rectangle.perimeter()); /// 600
    print(square.perimeter());  /// 400 
}

(5).工厂构造函数

有时候为了返回一个之前已经创建的缓存对象,原始的构造方法已经不能满足要求
于是工厂模式就应运而生, 这里工厂模式不作为我们的研究对象。

在Dart中我们可以使用工厂模式来定义构造函数
并且用关键字new来获取之前已经创建的缓存对象


class Logger {
  final String name;
  bool mute = false;

  // 变量前加下划线表示私有属性
  static final Map<String, Logger> _cache = <String, Logger>{};

  factory Logger(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
    } else {
      final logger = new Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }

  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) {
      print(name + ": "+ msg);
    }
  }
}

void main(){
  var logger = new Logger('UI');
  logger.log('Button clicked');
  logger.log('Button clicked2');
}

5. 容器

软件开发中容器的重要性就不多说了,下边开始学习。

(1).List

列表,也就是常说的数组 在Java中我们常用 ArrayList, LinkedList
在Dart中
常见的添加、索引、删除等方法如下

// 使用List的构造函数,也可以添加int参数,表示List固定长度
var vegetables = new List();

// 或者简单的用List来赋值
var fruits = ['apples', 'oranges'];

// 添加元素
fruits.add('kiwis');

// 添加多个元素
fruits.addAll(['grapes', 'bananas']);

// 获取List的长度
print(fruits.length == 5);

// 利用索引获取元素
print(fruits[0] == 'apples');

// 查找某个元素的索引号 , 这个索引获取的方法和Java一样 
print(fruits.indexOf('apples') == 0);

// 利用索引号删除某个元素
var appleIndex = fruits.indexOf('apples');
fruits.removeAt(appleIndex);
print(fruits.length);  ///  4  

// 删除所有的元素
fruits.clear();
print(fruits.length) /// 0  

打印结果:

true
true
true
4
0

在Java中我们可以使用Collections 和Arrays 数组工具集合类的方法来操作。
在Dart中可以使用sort()对List的元素进行排序
并且必须制定比较两个对象的函数,函数的返回值中
return <0 表示小于,0表示相同,>0表示大于

var fruits = ['bananas', 'apples', 'oranges'];
  这个方法和Java中的Comparable 的使用方法很相似 , 添加了排序规则方法。 
fruits.sort((a, b) => a.compareTo(b));

assert(fruits[0] == 'apples');

List以及其他的容器可以指定参数类型

// 下面的List只能包含String
var fruits = new List<String>();

fruits.add('apples');
var fruit = fruits[0];
assert(fruit is String);

fruits.add(5); // 错误: 在checked mode中会抛出异常  这一点和 Java中的数组是一样的。  

(2).Set

集合在Dart中无序,并且每个元素具有唯一性
因为它是无序的,因此你不能像List那样用索引来访问元素

var ingredients = new Set();

ingredients.addAll(['gold', 'titanium', 'xenon']);
assert(ingredients.length == 3);

// 添加已存在的元素无效
ingredients.add('gold');
assert(ingredients.length == 3);

// 删除元素
ingredients.remove('gold');
assert(ingredients.length == 2);

// 检查在Set中是否包含某个元素
assert(ingredients.contains('titanium'));

// 检查在Set中是否包含多个元素
assert(ingredients.containsAll(['titanium', 'xenon']));
ingredients.addAll(['gold', 'titanium', 'xenon']);

// 获取两个集合的交集
var nobleGases = new Set.from(['xenon', 'argon']);
var intersection = ingredients.intersection(nobleGases);
assert(intersection.length == 1);
assert(intersection.contains('xenon'));

// 检查一个Set是否是另一个Set的子集
var allElements = ['hydrogen', 'helium', 'lithium', 'beryllium',
'gold', 'titanium', 'xenon'];
assert(ingredients.isSubsetOf(allElements));

(3).Map

映射,也有人称之为字典
Map是一个无序的键值对容器

// Map的声明
var hawaiianBeaches = {
    'oahu' : ['waikiki', 'kailua', 'waimanalo'],
    'big island' : ['wailea bay', 'pololu beach'],
    'kauai' : ['hanalei', 'poipu']
};
var searchTerms = new Map();

// 指定键值对的参数类型
var nobleGases = new Map<int, String>();

// Map的赋值,中括号中是Key,这里可不是数组
nobleGase[54] = 'dart';

//Map中的键值对是唯一的
//同Set不同,第二次输入的Key如果存在,Value会覆盖之前的数据
nobleGases[54] = 'xenon';
assert(nobleGases[54] == 'xenon');

// 检索Map是否含有某Key
assert(nobleGases.containsKey(54));

//删除某个键值对
nobleGases.remove(54);
assert(!nobleGases.containsKey(54));

你可以用getKeys和getValues获取所有Key或者所有Values的迭代器

var keys = hawaiianBeaches.getKeys();
assert(keys.length == 3);
assert(new Set.from(keys).contains('oahu'));

var values = hawaiianBeaches.getValues();
assert(values.length == 3);

//迭代器中有一个有意思的函数any,用来检测迭代器中的数据
//当其中一个元素运行函数时return true,那么any的返回值就为true,否则为false
//与之相对的是函数every,要所有函数运行函数return true,那么every返回true
assert(values.any((v) => v.indexOf('waikiki') != -1));

// 你可以用foreach来遍历数据,但记住它是无序的
hawaiianBeaches.forEach((k,v) {
print('I want to visit $k and swim at $v');
});

//检索是否包含某个Key或Value
assert(hawaiianBeaches.containsKey('oahu'));
assert(!hawaiianBeaches.containsKey('florida'));

//V putIfAbsent(K key, Function V ifAbsent())函数,通过Key来查找Value
//当某个Key不存在的时候,会执行第二参数的Function来添加Value
var teamAssignments = {};
teamAssignments.putIfAbsent('Catcher', () => 'Catcher'.length);
assert(teamAssignments['Catcher'] != null);

这个操作和Java中的Map操作很相似 没什么好说的,多使用就是了。

(4).迭代

Set、List、Map都继承自Iterable,是可以迭代的

//如果迭代的对象是容器,那么可以使用forEach或者for-in
var collection = [0, 1, 2];

collection.forEach((x) => print(x));//forEach的参数为Function

for(var x in collection) {
    print(x);
}

打印结果:

0
1
2
0
1
2

6. 库的引用

在Dart中,你可以导入一个库来使用它所提供的功能
库的使用可以使代码的重用性得到提高,并且可以更好的组合代码
当然,你也可以自己定义一个库

Dart中任何文件都是一个库,即使你没有用关键字library声明
关键词import 和 Java中的import 一样

(1).import

import语句用来导入一个库
后面跟一个字符串形式的Uri来指定表示要引用的库

//dart:前缀表示Dart的标准库,如dart:io、dart:html
import 'dart:math';

//当然,你也可以用相对路径或绝对路径的dart文件来引用
import 'lib/student/student.dart';

//Pub包管理系统中有很多功能强大、实用的库,可以使用前缀 package:
import 'package:args/args.dart';

当各个库有命名冲突的时候,可以使用as关键字来使用命名空间

import 'lib/student/student.dart' as Stu;
Stu.Student s = new Stu.Student();

show关键字可以显示某个成员(屏蔽其他)
hide关键字可以隐藏某个成员(显示其他)

import 'lib/student/student.dart' show Student, Person;
import 'lib/student/student.dart' hide Person;

这种情况很少见,但是碰上了我们也是要知道如何解决的。

(2).library

library定义这个库的名字
但库的名字并不影响导入,因为import语句用的是字符串Uri

library person;

(3).part和part of

为了维护一个库,我们可以把各个功能放到各个dart文件中
但part of所在文件不能包括import、library等关键字
可以包含在part关键字所在文件中

建议避免使用part和part of语句,因为那样会使代码很难阅读、修改,可以多用library
part加字符串类型的Uri类似include,表示包含某个文件
part of加库名表示该文件属于那个库

// math.dart文件开头
library math;
part 'point.dart';
part 'random.dart';

// point.dart文件开头
part of math;

// random.dart文件开头
part of math;

看起来挺懵逼的, 算了明白知道有这东西就行了。 尽量不要使用。

(4).export

你可以使用export关键字导出一个更大的库

library math;

export 'random.dart';
export 'point.dart';

也可以导出部分组合成一个新库

library math;

export 'random.dart' show Random;
export 'point.dart' hide Sin;

本人觉得这玩意儿很少使用, 知道即可,不懂再查。

(5).利用Pub管理自己的库

这中间有个pubspec.yaml 的文件, Pub来管理自己的库
以便引用简洁,并且可以在yaml文件中很好的控制版本信息

environment:
  sdk: '>=1.20.1 <2.0.0'
#dependencies:
#  path: ^1.4.1
    http: ^0.12.0+2
#dev_dependencies:
#  test: ^0.12.0
#  http: ^0.12.0+2

7.总结

先这么着吧, Dart中一些简单基础语法先介绍到这里,后续会持续更新一些Dart的功能块化学习文章。 由于笔者能力有限文中有错在所难免,如有不对的地方,欢迎批评指正。

8.参考链接

a. CNDartLang社区
b. Dart language Dev
c. Flutter官网

参与评论 您还未登录,请先 登录 后发表或查看评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页

打赏作者

samuelnotes

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值