dart基础

[TOC]

主要介绍dart的一些语言规范和语法。

dart入口函数

main(){
    print("hello");
}

void main(){
    print("hello");
}

变量

dart可以通过var来定义变量,可以自动推导出变量类型;也可以显示的声明变量类型。

void main(){
  var name = "lili";
//  name = 123;//这里编译器就会报错,因为dart2.x是强类型语言,有类型校验,之间声明时已经将name自动推导为string,这点和python等弱类型语言不同
  String address = "china";
  int age = 1;
}

变量命名规则:

  • 变量名必须由数字、字母、下划线和美元符号($)组成。
  • 数字不能开头。
  • 不能是保留字和关键字。
  • 区分大小写。

常量

dart中使用final和const来定义一个常量。

两者的主要区别在于final可以用于修饰运行时常量,它只能被赋值一次,在使用时初始化;而const只能用于修饰编译时常量。

void main() {
  const name = "lili";
  final age = 11;

  //const date_1 = new DateTime.now();//错误:Const variables must be initialized with a constant value.
  final date_2 = new DateTime.now();
}

常用数据类型

  • int:只能是整型

  • double:可以是浮点型或者整型

    void main() {
      int a = 1;
      double b = 2;
      double c = 3.5;
    }
    
  • String

    void main() {
      var name = "lili";
      //字符串拼接
      print("hello $name");
      print("hello " + name);
    
      var address = """
      窗前明月光,
      疑是地上霜
      """;
      print(address);
    }
    
  • bool:true或false

  • List/Set

    void main() {
      var list_1 = [1,2,3];
      var list_2 = [1,2,"3"];
      var list_3 = new List();
      var list_4 = new List<int>();//指定集合类型
      var list_5 = new List(3);//指定集合长度
    }
    
  • Map

    void main() {
      var map_1 = {"name":"lili","age":18};
      var map_2 = new Map();
      var map_3 = new Map<int,String>();//key可以不为string
      map_3[1]="123";
    }
    

可以用is关键字来进行类型判断,等同于java中的instance。

运算符

运算符 具体符号及代表意义
算术运算符 +、-、*、/、%、~/(向下取整)
关系运算符 == 、!=、>、<、<=、>=
逻辑运算符 !、&&、||
赋值运算符 =、??=(为空才赋值)、+=、-=、*=、/=、%=、~/=、++、--
条件表达式 if else、switch case(同java)
三目运算符 ?:(同java)
??运算符 ??
void main() {
  var a = 2;
  var b = 3;
  print(a ~/ b); //0
  print(1 / 0); //Infinity

  a ??= 4;
  print(a); //2  因为a不为空,所以没有赋值为4

  var c = a ?? 5;
  print(c); //2  如果a为空,则c=5,否则c=a

  var e;
  print(a); //2
  e ?? a++;
  print(a); //3
}

循环

  • for循环
  • while循环
  • do...while循环

三者的使用方式基本同其他编程语言,这里简单介绍下。

for

void main() {
  for (int i = 0; i < 10; i++) {
    print(i);
  }

  var list = [1,2,3];
  for(var item in list){
    print(item);
  }
}

while和do...while

void main() {
  int i = 0;
  while(i<10){
    print(i);
    i++;
  }

  i = 0;
  do{
    print(i);
  }while(i<10);
}

break和continue

  • break:停止当前循环
  • continue:跳过当前循环体,继续下一次循环

函数

函数的定义

返回类型 方法名称(参数列表){

​ 方法体;

​ return 返回值;

}

返回类型可以省略,会自动推导。

函数的嵌套

dart中的方法是可以嵌套的,此时内部方法只能在外部方法内调用:

void main() {

  int sum(int a,int b){
    return a+b;
  }
  print(sum(1, 2));//3
}

可选参数

通过[]可以声明一组可选参数,可选参数可以有默认值。如果调用方法时没有传入该可选参数,则会使用它的默认值,如果没有默认值则默认为null。

注意可选参数必须写在参数列表的末尾。

void main() {

  printInfo(String a,[String b,String c = "c"]){
    print("$a $b $c");
  }

  printInfo("a");//a null c
  printInfo("a","b");//a b c
  printInfo("a","b","d");//a b d
}

命名参数

通过{}可以声明一组命名参数,命名参数也可以有默认值。

注意命名参数也必须写在参数列表的末尾。

void main() {
  printInfo(String a, {String b, String c = "c"}) {
    print("$a $b $c");
  }

  printInfo("a"); //a null c
  printInfo("a", b: "b"); //a b c
  printInfo("a", c: "d"); //a null d  可以跳过参数b直接传参数c
}

命名参数比可选参数一个方便的地方在于可以指定要传入的参数,而可选参数只能从前到后依次传入。

函数参数

dart中函数可以作为一个参数传入另一个函数。

void main() {
 fn1(){
   print("fn1");
 }

 fn2(f){
   f();
 }

 fn2(fn1);//fn1
}

箭头函数

对于一些简单的函数,可以使用箭头函数来进行简化。需要注意的是箭头函数后面只能写一句代码,并且它会把这句代码的值返回。

void main() {
  printInfo(Object info) => print(info);

  sum(int a,int b) => a+b;

  printInfo(sum(1, 2));//3

  var list = [1,2,3];
  var newList = list.map((item) => item*2);
  print(newList.toList());//[2, 4, 6]
}

匿名函数

匿名函数一般作为一个参数传入另一个方法,也可以使用一个变量来接收,方便之后调用。

void main() {
  var list = [1,2,3];
  list.map((item) => item*2);//(item) => item*2就是一个匿名方法

  var f1 = (){
    print("匿名方法");
  };
  f1();//匿名方法

  var f2 = (int a){
    print("匿名方法$a");
  };
  f2(2);//匿名方法2
}

自执行函数

自执行函数指不需要开发者调用,程序执行到这里就会自动运行的方法。

void main() {
  (() {
    print("123");
  })();//123

    
  ((int n) {
    print(n);
  })(456);//456
}

闭包

闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。变量的作用域仅限于包含它们的函数,因此无法从其它程序代码部分进行访问。不过,变量的生存期是可以很长,在一次函数调用期间所创建所生成的值在下次函数调用时仍然存在。正因为这一特点,闭包可以用来完成信息隐藏,并进而应用于需要状态表达的某些编程范型中。

在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。

void main() {
  f(){
    var num = 1;
    return (){
      print(num);
      num++;
    };
  }

  f()();//1
  f()();//1
  f()();//1

  var a = f();
  a();//1
  a();//2
  a();//3
}

类与对象

dart是一门面向对象编程(OOP)的语言。它同样有封装、继承、多态三大特征。

  • 所有能够使用变量引用的都是对象, 每个对象都是一个的实例。在 Dart 中 甚至连 数字、方法和 null都是对象。dart中所有对象都继承于Object。
  • dart支持顶级函数和在类中定义函数(可以理解为静态函数和实例函数)。
  • dart同样也支持顶级变量。

默认构造函数

dart中默认构造函数只能有一个。

以下两种写法是等价的:

class Student {
  String name;
  int age;

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

class Student {
  String name;
  int age;

  Student(this.name, this.age);
}

命名构造函数

dart中命名构造函数可以有多个。

dart中类实例化时new关键字是可以省略的。

void main() {
  var student_1 = Student("lili", 18);//调用默认构造函数
  var student_2 = Student.name("tom");
  var student_3 = Student.newInstance("lili", 18);
}

class Student {
  String name;
  int age;

  Student(this.name, this.age);

  Student.name(this.name);

  Student.age(this.age);

  Student.newInstance(this.name, this.age);
}

类的初始化列表

类的初始化列表运行在构造函数体运行之前。

class Student {
  String name;
  int age;
  String address;

  Student(this.name)
      : this.age = 18,
        assert(name != null);
}


import 'Student.dart';

void main() {
  var student_1 = Student("lili");
  print(student_1.name);//lili

  var student_2 = Student(null);// Failed assertion: line 8 pos 16: 'name != null': is not true.
  print(student_2.name);
}

访问修饰符

dart中是没有public、private这些访问修饰符的,我们可以通过将属性或方法名以_开头来表示私有。

import 'Student.dart';

void main() {
  var student_1 = Student("lili", 18);//调用默认构造函数
  print(student_1.name);//lili
//  print(student_1._age);//报错
}

class Student {
  String name;
  int _age;

  Student(this.name, this._age);

  study(){
    print("学习");
  }
}

getter/setter

class Student {
  String name;
  int _age;

  get age => this._age;
  
  set age(int age) {
    this._age = age;
  }
}

静态成员

  • 使用static关键字来实现类级别的属性和方法。
  • 静态方法不能访问非静态属性,非静态方法可以访问静态属性。
class Student {
  static String name = "lili";
  int age;
  String address;

  static study(){
    print("学习");
  }
}


import 'Student.dart';

void main() {
  print(Student.name);//lili
  Student.study();//学习
}

对象操作符

  • ? 条件运算符
  • as 类型转换
  • is 类型判断
  • .. 级联操作
class Student {
  String name;
  int age;

  printInfo(){
    print("$name $age");
  }
}


import 'Student.dart';

void main() {
  Student student;
//  student.printInfo();//报错 空指针异常
  student?.printInfo(); //不会执行study方法,但是也不会报错

  Object object = Student();
  (object as Student).printInfo(); //null null

  if (object is Student) object.printInfo(); //null null

  student = Student();
  student.name = "lili";
  student.age = 18;
  student.printInfo(); //lili 18

  student
    ..name = "tom"
    ..age = 20
    ..printInfo();//tom 20
}

继承

  • 子类使用extends关键字继承父类
  • 子类会继承父类里面可见的属性和方法,但不会继承构造函数(如果父类构造函数有参数的话,子类构造函数必须调用父类的构造函数并传入参数)
  • 子类能复写父类方法,包括getter和setter
class Person{
  String name;
  int age;

  Person(this.name, this.age){
    print("Person构造函数");
  }

  Person.name(this.name);

  run(){
    print("走路");
  }
}

class Student extends Person{
  String school;

  Student(String name, int age) : super(name, age);

  Student.school(String name, int age,this.school) : super(name, age);
  Student.school2(String name,this.school) : super.name(name);

  @override
  run() {
    // TODO: implement run
    return super.run();
  }
}

抽象类

  • 抽象类通过abstract关键字来定义
  • 抽象方法不能使用abstract声明,dart中没有方法体的方法我们称为抽象方法
  • 继承抽象类必须实现里面的所有抽象方法
  • 抽象类不能直接实例化
abstract class Person{
  eat();//抽象方法
  printInfo(){
    print("Person printInfo");
  }
}

class Student extends Person{
  @override
  eat() {
    // TODO: implement eat
    return null;
  }
}

接口

dart中也有接口的概念,但是和Java中的接口有所不同:

  • dart中没有interface关键字
  • 普通类和抽象类都可以作为接口通过implements关键字被实现
  • 一个类作为接口的话,它的实现类需要将接口类中所有的属性和方法都复写一遍
  • 一个类可以实现多个接口
abstract class Person{//接口一般用于定义规范、标准
  String name;
  work();//抽象方法
}

abstract class Anim{
  eat();
}

class Student implements Person,Anim{
  @override
  String name;

  @override
  eat() {
    // TODO: implement eat
    return null;
  }

  @override
  work() {
    // TODO: implement work
    return null;
  }
}

mixins

dart中可以使用mixins实现类似多继承的功能。

  • 作为mixins的类只能继承自Object,不能继承其他类
  • 作为mixins的类不能有构造函数
  • 一个类可以mixins多个mixins类
  • 使用with关键字
  • 可以先extends,再with
  • mixins不是继承,也不是接口,而是一种新的特性
abstract class Person {
  //接口一般用于定义规范、标准
  String name;

  work(); //抽象方法
}

abstract class Anim {
  eat();
}

class Student with Person, Anim {
  @override
  eat() {
    // TODO: implement eat
    return null;
  }

  @override
  work() {
    // TODO: implement work
    return null;
  }
}

泛型

泛型的使用基本同Java。

class Person<T extends Object> {
  List<T> list;

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

异常处理

dart中的异常处理可以使用 try/on/catch/finally 块。

try异常块嵌入代码,有可能会导致异常。需要指定异常类型时使用on块。catch块,需要捕捉异常时使用。

test() {
  try {
    Person p;
    p.getData(1);
  } on NoSuchMethodError {//如果发生的是NoSuchMethodError异常,则会执行on代码块,其他异常则会执行catch代码块
    print("on Exception");
  } catch (e) {
    print("catch Exception");
  } finally {//无论是否发生异常都会执行
    print("finally");
  }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容

  • Dart语法基础 Dart语言简介 Dart是Google推出的一门编程语言,最初是希望取代Javascript运...
    张叔叔阅读 10,507评论 1 9
  • 基础入门 由于本教程需要具有一定开发经验的阅读者才可以真正理解,因此建议阅读者在向下学习前先掌握以下基础技能: 基...
    crixusshen911阅读 1,023评论 0 51
  • Flutter应用是采用Dart语言来编写,在学习Flutter之前,我们有必要先学习一下Dart语言。Dart是...
    云飞扬1阅读 1,005评论 0 50
  • Dart基础语法 基本数据类型 Dart 属于强类型语言(在Dart2.0之前,Dart是一门弱类型语言。2.0以...
    烫烫琨烫烫烫烫琨烫烫阅读 2,784评论 0 0
  • 那条路可以昂首不悔走到最后, 唯有人生这条路可以如此自由。
    南窗饮风阅读 282评论 1 4