Flutter开发必备Dart基础:Dart快速入门

待兔 等级 609 0 0

概述

Dart从2.0开始变为强类型语言,静态类型。这点和Java、C#等比较相似。也就是说在编译时就已经知道变量的类型那么就是静态类型语言。开发人员在开发的时候需要指定变量的类型。这有什么优点呢? 就是所有类型检查都可以通过编译器来完成。可以提前预报一些琐碎的错误。
同时Dart还是面向对象的编程语言。像python、Java、Koltin、PHP等等都是面向对象的语言。

dart的特性:
JIT:即时编译,开发期间做到更快的编译和更快的代码重载。 但也有劣势就是在运行时需要将代码编译为机械码,那么直观感受就是慢,所以我们在开发期间有时候会发现卡顿,但是打release包之后效果会变好的原因。
AOT:事前编译,release期间已经编译为二进制代码,所以加载会更快更流畅。

常用数据类型

任何语言的基础都是数据类型,dart也一样。dart中主要有数字、字符串、布尔、集合和var类型。

num类型

num是dart中的数字类型的父类,它有两个子类:int和double。当类型指定为num的时候可以赋值为小数也可以赋值为整数,但是一旦指定了某一个具体的类型,就只能赋值这一类型的值。

  void _numType() {
    num num1 = -2.0; //定义为小数
    num num2 = 4; //定义num为你太
    int num3 = 5; //只能是整数
    double num4 = 6.0; //只能是双精度
  }

其中这些类型之间是可以相互转换的,如:

    print(num1.abs()); // 取绝对值 输出 2.0
    print(num2.toDouble()); // 转为小数 输出4.0
    print(num3.toString()); // 转为字符串 输出"5"
    print(num4.toInt()); // 转为整数 输出 6

String类型

String的定义也比较简单,它可以使用单引号也可以使用双引号定义,定义一个String类型后面可以通过逗号隔开定义多个变量。在dart中拼接字符串可以是 + 号链接,还可以使用 Flutter开发必备Dart基础:Dart快速入门xx,如果是表达式则使用${xxx}将其包裹起来。

  void _stringType() {
    String str1 = 'str1', str2 = "str2"; //定义字符串str1和str2
    String str3 = "字符串数据类型"; //定义字符串str3
    String str4 = 'str1=$str1;str2=$str2'; //通过$符拼接字符串
    String str5 = "str1=" + str1 + " str3=" + str3; //通过+号拼接字符串
  }

字符串还有一些常用的API,比如字符串截取,获取指定字符串位置,匹配字符串开头等等。

    print(str3.substring(1, 5)); //符串数据 输出 符串数据
    print(str3.indexOf("数据")); // 获取位置 输出 3
    print(str3.startsWith("字")); //匹配起始字符串 true
    print(str3.replaceAll("字符串", "dart的String")); //替换 输出dart的String数据类型
    print(str3.split("数")); //切够字符串 输出[字符串,据类型]

布尔类型

dart中布尔类型是强bool类型,只有bool类型的值为true,才被认为是true。bool还有一些常用的运算符比如 ||(或) 或者 &&(且) ,在运算的时候,教大家一个口诀就是,且同真为真,或同假为假。

  void _boolType() {
    bool success = true; //定义bool值为true
    bool failure = false; //定义bool值为false

print(success || failure); //或运算 输出 true
print(success && failure); //且运算 输出 false

}

集合类型

dart中定义集合直接使用List list=[],如果没有指定泛型,默认类型为dynamic类型,集合中可以添加任何数据类型的数据,一旦指定了泛型,那么就只能添加约束的类型数据。除了初始化的时候添加元素另外还可以通过API的方式像集合中添加数据,add添加单一数据,addAll添加集合。还有另外一种方式是通过List.generate来生成集合,它的第一个参数表示集合的大小,第二个参数表示集合的元素。

  void _listType() {
    List list = [1, 2, 3, "list"]; //泛型为dynamic
    //报 type 'List<dynamic>' is not a subtype of type 'List<int>' 异常
    //因为指定了intList的泛型为int 但是list的泛型为dynamic,随意赋值失败
    //List<int> intList = list;
    List<int> intList2 = [1, 2, 3, 4, 5]; //定义int集合
    list.add("hello"); //添加单一元素
    list.addAll(intList2); //添加集合
    print(list); //输出 [1, 2, 3, "list","hello",1, 2, 3, 4, 5]

List&lt;String&gt; strList = List.generate(2, (index)=&gt; "我是第$index个元素"); //通过generate定义一个String集合
print(strList); //输出 [我是第0个元素, 我是第1个元素]

}

有了集合那么我们就需要遍历它,dart中常用的遍历集合方式有:

    for (int i = 0; i < list.length; i++) {
      print(list[i]);
    }

for (var data in list) {
  print(data);
}

list.forEach((it) {
  print(it);
});

上面三种遍历方式输出结果都为:

1, 2, 3, "list","hello",1, 2, 3, 4, 5

Map类型

Map类型是将key和value相关联的对象,key和value可以是任意类型的数据,并且key是唯一的,如果key重复那么后添加的会覆盖之前添加的数据。定义map类型直接看代码:

  void _mapList() {
    Map map = {"lisi": 20, "zhangsan": 24}; //直接通过 {key:value} 方式定义
    Map map2 = {};
    map2[11] = 20;
    map2["zhangsan"] = "24";
    //上面两个效果是一样的且都没有指定泛型。

Map&lt;int, int&gt; intMap = {1: 2, 3: 4}; //指定map的泛型

}

下面我们看下Map的遍历:

    map.forEach((key, value) {
      print(
          "key:$key,value:$value"); //输出 key:lisi,value:20 和 key:zhangsan,value:24
    });

map.map((key, value) {
  return MapEntry(value, key); //返回一个新的map对象,我们将key value值进行颠倒后返回
}).forEach((key, value) {
  print("key:$key,value:$value"); //输出 key:20,value:lisi 和 key:24,value:zhangsan
});

for(var key in map.keys){ //遍历map的key元素 同理还可以遍历map.values
  print(key); //输出 lisi 和 zhangsan
}

dynamic、var、Object的区别

dynamic:动态数据类型,是所有Dart对象的基础类型, 在大多数情况下,通常不直接使用它,通过它定义的变量会关闭类型检查,这意味着 dynamic x = 'hello world'; 调用x.foo()方法时静态类型检查不会报错,但是运行时会crash,因为x并没有foo()方法,所以建议大家在编程时不要直接使用dynamic。

var:是一个关键字,意思是“我不关心这里的类型是什么。”,系统会自动推断类型runtimeType;而且一旦指定了类型,就不可以修改。

Object:是Dart对象的基类,当你定义:Object obj=xxx 时这时候系统会认为obj是个对象,你可以调用obj的toString()和hashCode()方法,因为Object提供了这些方法,但是如果你尝试调用obj.foo()时,静态类型检查会进行报错。

综上不难看出dynamic与Object的最大的区别是在静态类型检查上。

面向对象

类的定义和构造

定义一个dart类,使用class关键字加上类名,构造方法和类名相同,默认所有的类都是继承Object的。其中可以定义一些方法和变量,如:

class Person {
  String name;
  int age;

//标准构造方法 Person(this.name, this.age);

//重载父类的toString方法 也是多态的重要体现 @override String toString() { return "name=$name,age=$age"; } }

一个类继承另一个类使用关键字extends,如果父类没有默认无参构造函数,那么子类需要使用super对父类进行初始化,子类的变量使用this.xxx来指定初始化,如:

class Worker extends Person {

String workType; String workAddress; //通过this来初始化子类字段,将其他字段交由父类初始化 Worker(this.workType,this.workAddress,String name, int age) : super(name, age); }

上面代码中的 :super(name,age) 被称作为初始化列表,除了调用父类构造器,还可以初始化实例变量,不同的初始化变量之间用逗号隔开。

class Worker extends Person {

String workType; String workAddress; String companyName;

//通过this来初始化子类字段,将其他字段交由父类初始化,这里指定了companyName的初始化。 //如果要初始化变量,那么其不可以在构造方法中定义 Worker(this.workType, this.workAddress, String name, int age) : companyName = "world", super(name, age); }

我们还可以通过命名构造函数的方式初始化实例类。使用就是 类名.xx() 即可,主要注意的是当有变量的类型是final的时候,命名构造方法就要求其在构造方法中指定初始化。

class Worker extends Person {

......

//命名构造函数 Worker.begin(Worker work) : super(work.name, work.age) { print("命名构造函数"); }

//假如有变量final String workAddress,那么就需要在构造方法中指定: //Worker.begin(Worker work,this. workAddress) : super(work.name, work.age) { // print("命名构造函数"); //}

}

工厂构造函数就是都只返回同一个实例类,可以理解为Java中的单例模式。

class Logger {
  static Logger _logger;

factory Logger() { if (_logger == null) { _logger = Logger._initInstance(); } return _logger; }

//通过命名构造函数初始化 Logger._initInstance(); }

还有一种构造方法是命名构造和工厂构造的结合体,通常在网络请求的时候将json映射为object的时候使用,它有一个好处就是不需要将类的final变量作为参数传递给构造方法。提供了一种灵活获取类对象的方式。定义格式:factory 类名.方法名。

class Worker extends Person {

......

factory Worker.workHard(Worker work) { return Worker.begin(work, ""); } }

dart默认都会隐式的定义setter方法,对非空的变量还会增加getter方法。但是加了私有后,外界就无法访问变量了,需要我们手动的添加set和get方法。

class Worker extends Person {

......

double _salary;

set salary(double value) => _salary = value;

get salary => _salary;

......

}

抽象类和方法

使用 abstract 修饰符来定义一个抽象类,该类不能被实例化。抽象类在定义接口的时候非常有用,实际上抽象类中也包含一些实现。如果一个类继承了抽象类要么实现它的抽象方法,要么也将自己定义成抽象类。一个抽象类中不一定要有抽象方法,但是有抽象方法的类一定是抽象类。

//抽象类
abstract class Animal {
  //抽象方法
  void eat();
}

//实现抽象类 class Dog extends Animal { //实现eat方法 @override void eat() { print("啃骨头"); } }

mixins

mixins 是在多个类层次结构中重用代码的一种方式。要使用 mixins ,在 with 关键字后面跟一个或多个 mixin 的名字(用逗号分开),并且with要用在extends关键字之后。

mixins的特征:实现 mixin ,就创建一个继承 Object 类的子类(不能继承其他类),不声明任何构造方法,不调用 super。

//声明mixins类
class Pig {
  void action() {
    print("吃完就睡");
  }
}

//使用mixins类,可以复用它的action方法 class Cat extends Animal with Pig { @override void action() { print("抓老鼠"); }

@override void eat() { print("吃猫粮"); } }

方法定义

方法是由返回值类型+方法名+参数构成。其中返回值类型可缺省,也可为void或者具体的类型。正常情况下都是由方法名的,但有一种特殊就是匿名方法。参数分为参数类型和参数名,其中参数类型可缺省。参数又分为可选参数和默认参数,他们都使用 {} 来定义。

class FunClass {
  //city为可选参数,town为默认参数
  String fromWhere(country, {String city, String town = "小红帽村"}) {
    if (city != null) {
      return "我来自 $country $city $town";
    } else {
      return "我来自 $country $town";
    }
  }
}

我们来调用打印下看看:

FunClass funClass = FunClass();
print(funClass.fromWhere("格林国")); //输出 我来自 格林国 哈哈村
print(funClass.fromWhere("格林国", city: "童话镇"));//输出 我来自 格林国 童话镇 哈哈村

匿名方法有时候也被称为 lambda 或者 closure 闭包,可以把匿名方法赋值给一个变量,直接调用变量名即可。

var printI = (i) => print(i); 

使用:

FunClass funClass = FunClass();
funClass.printI(999);

泛型

泛型主要是解决类、接口、方法的复用性、以及对不特定数据类型的支持。

class Cache<T> {
  static final Map<String, Object> _cached = Map();

void setItem(String key, T value) { _cached[key] = value; }

///泛型方法 T getItem(String key) { return _cached[key]; } }

这里我们定义了一个缓存类,存储的类型被定义为泛型,提高代码的复用度。

有时候我们在实现类似通用接口的泛型中,期望的类型是某些特定类型时,这时可以使用类型约束。

class Member<T extends Person> {
  T _person;

///泛型作用:约束参数类型 Member(this._person);

String fixedName() { return 'fixed:${_person.name}'; } }

总结

本文主要是讲解了在Flutter中常用到的dart的基础知识,当然还有其他很多的知识点没有涉及到。这里推荐几个dart学习网站给大家使用。

https://www.dartlang.org

https://dart.dev/guides/language/language-tour

http://dart.goodev.org/guides/language/language-tour

收藏
评论区

相关推荐

Dart官方文档翻译(一)(Dart之旅)
这篇文章将会向你展示如何使用Dart的每一个知识点,包括变量,操作符,类,类库,但这是在你已经有一个其他语言的编码经验的前提下。 为了学习Dart更多关于Dart的核心类库,请查看A Tour of the Dart Libraries,当你想知道更多语言特征,挺查阅Dart language specification 你可以通过DartPad 来尝试
<Dart基础>Dart简介
Dart基础系列: Dart简介(https://www.jianshu.com/p/c749f40828a5) Dart语法(上)(https://www.jianshu.com/p/6b5689342e24) <基础Dart语法(下)(https://www.jianshu.com/p/7c3eba46e679) 一、简
Dart基础&gt;Dart语法(上)
Dart基础系列: Dart简介(https://www.jianshu.com/p/c749f40828a5) Dart语法(上)(https://www.jianshu.com/p/6b5689342e24) <基础Dart语法(下)(https://www.jianshu.com/p/7c3eba46e679) 说明:
Dart基础语法简介
Dart基础系列: Dart简介(https://www.jianshu.com/p/c749f40828a5) Dart语法(上)(https://www.jianshu.com/p/6b5689342e24) <基础Dart语法(下)(https://www.jianshu.com/p/7c3eba46e679) 一、简
flutter -- dart基础之dart简介和安装
Dart介绍: Dart是由谷歌开发的计算机编程语言,它可以被用于web、服务器、移动应用 和物联网等领域的开发。 Dart诞生于2011年,号称要取代JavaScript。但是过去的几年中一直不温不火。直到Flutter的出现现在被人们重新重视。 要学Flutter的话我们必须首先得会Dart。 da
Dart | 浅析dart中库的导入与拆分
前言 最近十分热门的跨平台框架使用了一门比较生僻的编程语言dart。dart语言本身深受早期一些编程语言的影响。特别是Smalltalk,Java和JavaScript。我是从Java语言向dart过度的,一开始感觉很不错,快速就对这门语言有了一个初步的认识,并能够写小段代码了。 但在flutter的不断学习过程中,我遇到了不少因为dart的一些语
Dart教程(一):dart安装
一、安装dart sdk brew tap dartlang/dart brew install dart 二、安装VSCode 去官网下载即可 三、安装dart插件 (https://imghelloworld.osscnbeijing.aliyuncs.com/af7d1de25caf6599a4839b56f4f0d
Dart 入门中文教程
一、开篇 dart 语言具有如下特性 一切变量皆是对象,每个对象都是类的实例。int、double、null、函数等都是对象,所有对象都继承自 Object 类 dart 是强类型语言,但由于具备类型推导功能所以类型声明是可选的 dart 支持顶级函数、静态函数、实例函数,也允许在函数中嵌套函数,即局部函数。类似的,dart 也支持顶级
【Flutter 实战】Dart语言简介
1.4 Dart语言简介在之前我们已经介绍过Dart语言的相关特性,读者可以翻看一下,如果读者已经熟悉Dart语法,可以跳过本节,如果你还不了解Dart,也不用担心,按照笔者经验,如果你有过其他编程语言经验(尤其是Java和JavaScript)的话会非常容易上手Dart。当然,如果你是iOS开发者,也不用担心,Dart中也有一些与Swift比较相似的特
【Flutter实战】Dart线程模型及异常捕获
2.6 Flutter异常捕获在介绍Flutter异常捕获之前必须先了解一下Dart单线程模型,只有了解了Dart的代码执行流程,我们才能知道该在什么地方去捕获异常。 2.6.1 Dart单线程模型在Java和ObjectiveC(以下简称“OC”)中,如果程序发生异常且没有被捕获,那么程序将会终止,但是这在Dart或JavaScript中则不会!
Dart中的抽象类、多态、以及接口
一、Dart中的抽象类 Dart中抽象类: Dart抽象类主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。   1、抽象类通过abstract 关键字来定义   2、Dart中的抽象方法不能用abstract声明
Flutter - 深入理解Dart虚拟机启动
基于Flutter 1.5,从源码视角来深入剖析引擎启动中的Dart虚拟机启动流程,相关源码目录见文末附录一、概述 1.1 Dart虚拟机概述Dart虚拟机拥有自己的Isolate,完全由虚拟机自己管理的,Flutter引擎也无法直接访问。Dart的UI相关操作,是由Root Isolate通过Dart的C调用,或者是发送消息通知的方式
Dart虚拟机运行原理
一、Dart虚拟机 1.1 引言Dart VM是一种虚拟机,为高级编程语言Dart提供执行环境,但这并意味着Dart在D虚拟机上执行时,总是采用解释执行或者JIT编译。 例如还可以使用Dart虚拟机的AOT管道将Dart代码编译为机器代码,然后运行在Dart虚拟机的精简版环境,称之为预编译运行时(precompiled runtime)环境,该环境不包含任何
Flutter 介绍、运行环境
Flutter 是谷歌公司开发的一款开源、免费的移动 UI 框架,可以让我们快速的在 Android 和iOS 上构建高质量 App。它最大的特点就是跨平台、以及高性能。 Flutter 基于谷歌的 dart 语言,如果没有任何 Dart 语言的基础,不建议直接学习 Flutter。建议先学习 Dart 语言的基本语法。然后再进入 Flutter 的学习
Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
此文转载自:https://blog.csdn.net/AndrExpert/article/details/110823218 总目录 === [Flutter开发指南之理论篇:Dart语法01(数据类型,变量,函数)](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fjiangd