哥哥带你回顾Dart

2019-05-18  本文已影响0人  哥哥是欧巴Vitory

Dart重要概念:

1,在变量中可以放置的所有东西都是对象,而每个对象都是类的实例。无论数字、函数、和null都是对象。所有对象都继承自object类。

2,尽管Dart是强类型的,但类型声明时可选的,因为Dart可以推断类型。如果要明确说明不需要任何类型,请使用特殊类型dynamic。

3,Dart支持通用类型,如List<int>整数列表或者List<dynamic>任何类型对象列表

4,Dart支持顶级函数,如main,以及绑定到类或者对象的函数(分别是静态方法和实例方法)。还可以在函数(嵌套或局部函数)中创建函数

5,Dart支持顶级变量,以及绑定到类或者对象的变量(静态和实例变量)。实例变量有时候被称为字段或者属性。

6,和Java不同的是,Dart没有公开、保护和私有的关键字。如果标识符以下划线开头,则该标识符对其库是私有的。

7,标识符可以是以字母或下划线开头,然后是这些字符加上数字的任何组合

8,有时候某事物是一个表达还是一个语句是很重要的,所以这两个词要准确。

9,Dart工具可以报告两种问题:警告和错误。警告只是表明代码可能不工作,但不会阻止程序执行。错误可以是编译时错误,也可以是运行时错误。编译时错误阻止代码的执行,运行时错误导致代码执行时引发异常。

1,变量

默认值:

未初始化的变量初始值为null,甚至具有数字类型的的变量最初也是null,因为数字就像dart中其他东西一样,也是对象。

注意:在生产环境中,assert调用被忽略。在开发环境中当assert(condition)的condition条件不为真时抛出一个异常。

Final 和 Const 修饰符:

如果从未向改变一个变量,使用final或const修饰。最终变量只设置一次,const是一个编译时常数(隐式的最终变量)最终的顶级或者类变量在第一次使用时被初始化。

注意:实例变量可以是final,但不能是const,【实例变量定义在对象一级,它可以被类中的任何方法或者其他类中的方法访问,但是不能被静态方法访问】

对于想要在编译时确定并且不再变的变量,使用const。如果const变量位于类级别,则将其标记为静态const。const关键字不仅可以声明常量变量,还可以创建常量值,以及声明创建常量值的构造函数。任何变量都可以赋一个常量值。可以从cosnt声明的初始化表示式中省略const,可以更改一个非final的非const变量的值,即使它曾经有一个const值。

数字字面量是编译时常量,许多算术表达式也是编译时常量,只要它们的操作数是编译时常量,就可以对数字进行求值。

Dart字符串是UTF-16编码,注意:==检验两个对象是否相等。如果两个字符串包含相同序列的代码单元,那么他们是等价的。可以使用相邻的字符串字面量+运算符连接字符串。可以用 r 前缀创建一个原始的字符串。字符串字面量是编译时常量,只要任何内插表达式都是编译时常量,计算结果为null 或数值、字符串或布尔值。

数组

var list = 【1,2,3】

注意:分析器推断该列表具有list<int>类型,如果试图想此列表添加非整型对象,则分析器或运行时引发错误。

map是一个关联键和值的对象,键和值都可以是任何类型的对象,每个键值出现一次,但是您可以多次使用相同的值。dart对map的支持是通过map字面量和map类型来提供的。

注意:解析器推断gifts的类型为Map<String, String>,nobleGases的类型为Map<int, String>。如果您试图向map添加错误类型的值,则分析器或运行时将引发错误。

var gifts = Map(); 在Dart中new关键字是可选的。要创建一个编译时常量的map需要在map的字面量钱加const关键字。

Rune(字符)

在dart中,字符是字符串的utf -32编码点。Unicode为世界上所有的书写系统中使用的每个字母、数字和符号定义唯一的数值。因为dart字符串是utf-13代码单元的序列,所以在字符串中表示32位的Unicode值需要特殊的语法。

注意:表示Unicode码点的常用方法是\uXXXX其中XXXX是4位数的十六进制值。例如,心型字符(♥)的编码为\ u2665。要指定大于或小于4位十六进制数字,请将值放在花括号中。例如笑脸表情(😆)的编码\u{1f600}.string类有几个属性可以用来获取Rune信息。codeUnitAt和codeUnit属性返回16位代码单元。使用字符属性获取字符串的字符。

注意:使用列表操作runes时要小心,根据特定的语言、字符串和操作,这种方法很容易出错。

symbols

符号常量是编译时常量。

2,函数

函数也是对象。可以分配给变量或者作为参数传递给其他函数。还可以向调用函数一样调用dart类的实例。

Effective Dart建议对公共api使用类型注释。

对于只包含一个表达式的函数,可以使用简写语法。

=>expr 语法是{return expr;}的简写写法。“=>”符号有时被称为胖箭头语法。注意:在箭头(=>)和分号(;)之间只能出现一个表达式(不是语句)。例如,您不能在那里放一个if语句,但是您可以使用一个条件表达式。

函数可以有两种类型的参数,必需的和可选的。首先列出必须的参数,后边是任何可选参数。命名可选参数也可以标记为@required。可选参数可以是位置参数也可以是命名参数,但不能两者都是。可以在任何Dart代码(不仅仅是Flutter)中注释一个已命名的参数,并使用@required说明它是一个必传的参数。

当构造Scrollbar时,分析器在没有子参数时报错。Required在元包中被定义。或者直接使用import package:meta/meta.dart导入或者导入其他包含meta导出的包,例如Flutter的包:Flutter /material.dart。

函数可以使用=来定义位置参数的默认值。默认值必须是编译时常量。如果没有提供默认值,则默认值为null。

弃用注释:旧代码可能使用冒号(:)而不是=来设置命名参数的默认值。原因是最初,只有:被命名参数支持。这种支持很可能被弃用,因此我们建议您使用=来指定默认值。

还可以把列表或map集合作为默认值。

main()

每个应用程序都必须有一个顶级 的main函数,它是应用程序的入口点。返回void,并有一个可选的列表参数作为参数。

...语法称为级联,使用级联可以对单个对象的成员执行多个操作。

可以使用args库来定义和解析命令行参数。

可以创建一个没有函数名称的函数,称为匿名函数,或者lambda函数,或者闭包函数,匿名函数看起来类似命名函数,有0个或者多个参数,在括号之间用逗号和可选类型标注分隔。后面的代码块包含函数的主体。

词法作用域

dart是一种在词法上确定范围的语言,意味着变量的范围是静态的。仅仅是通过代码的布局来决定的。可以通过花括号想外一查看变量是否在范围内。

词法闭包

闭包是一个函数对象,它可以访问其词法范围内的变量,及时函数在其原始范围之外使用。函数可以关闭周围作用域中定义的变量。

判断函数相等

测试两个对象x和y是否代表相同的东西,使用==操作符。需要知道两个对象是否完全相同的情况下,可以使用identical函数。

如果x或y为空,如果两个都为空,则返回true;如果只有一个为空,则返回false。

返回方法调用x.= (y)的结果。(==等操作符是在第一个操作数上调用的方法。您甚至可以覆盖许多操作符,包括==,您将在可覆盖操作符中看到)

??=操作符尽在变量为null时会赋值,未初始化和后来手动赋值为null情况都会执行此操作赋值。

级联表示法

级联允许在同一个对象上创建一个操作 序列。除了函数调用之外。可以访问同一对象上的字段。通常可以省去创建临时变量的步骤。

流程控制:

和js不同的是,条件不允许使用其他值,只能使用布尔值。

Assert(断言)

如果布尔值为false,则使用assert语句中断正常执行。注意:Assert语句不会影响生产环境中代码的执行,它仅仅在测试环境中起作用。在Flutter的调试模式下可以使用assert。默认情况下,像(dartdevc typically)只支持开发环境的工具默认支持assert。例如dart和dart2js通过命令行标记:--enable-asserts来支持asserts。

断言的第一个参数可以是任何解析为布尔值的表达式。如果表达式的值为true,则断言成功并继续执行。如果是false,则断言失败,并抛出异常(AssertionError)。

异常处理

dart代码可以抛出和捕获异常。dart所有异常都是未检查的异常,方法不声明可能抛出哪些异常,也不要求捕获异常。提供exception和error类,以及许多预定义的子类型。当然也可以自定义异常。但dart程序可以抛出任何非空对象不仅仅是异常和错误对象。

dart具有类和基于mixin的继承,每个对象都是一个类的实例,所有类都是object的子类。基于mixin继承意味着,尽管每个类(除了Object)都只有一个超类,但类主体可以多个类层次结构中重用。

构造函数名可以是ClassName或ClassName.identifier。

有些类提供常量构造函数,要使用常量构造函数创建编译时常量,请将const关键字放在构造函数名之前。构造两个相同的编译时常量会生成一个单一的,规范的实例。在常量上下文中,可以构造函数或文字之前省略const。

const关键字在dart2的常量上下文变成可选的。

获得类型对象

要在运行时获得对象类型,可以使用对象的runtimeType属性,该属性返回一个类型对象。

所有未初始化的实例变量都具有null值。都生成隐式的getter方法。非最终实例变量也生成隐式setter方法。

如果在声明实例变量的地方,而不是在构造函数或方法中初始化实例变量,则在创建实例时在构造函数及其初始化列表执行之前设置该值。

注意:只有在名称冲突时才使用,否则dart代码风格要省略this

如果不声明构造函数,则为您提供默认构造函数,默认构造函数没有参数,并在超类中调用五参数构造函数。

一定要记住构造函数是不会从父类继承的,这意味着父类的命名构造函数子类也不会继承。如果你希望使用在超类中定义的命名构造函数来创建子类,则必须在子类中实现该构造函数。

调用非默认的超类构造函数

默认情况下,子类中的构造函数调用父类的未命名无参数构造函数。父类的构造函数体的开始处被调用。如果类中有使用初始化列表。初始化列表将在调用超类之前执行。执行顺序如下:

1,初始化列表

2,超类中的无参数构造函数

3,main类中的无参数构造函数

注意:在超类的构造函数的参数中不能使用this关键字,例如,参数可以调用static方法但是不能调用实例方法。

初始化列表

可以通过在初始化列表中使用assert来验证输入。

初始化列表在设置final字段时很方便。

重定向构造函数

常量构造函数

工厂构造函数

getter 和 setter方法

抽象方法

抽象类

使用abstract修饰符定义不能实例化的抽象类。抽象类对于定义接口非常有用。如果希望抽象类可实例化,可以定义工厂构造函数。

隐式接口

每个类都隐式的定义一个接口,该接口包含类的所有实例成员及其实现的任何接口。如果想创建一个类A,它支持B的api而不继承B的实现,那么类A应该实现B接口。

扩展类

使用extend创建子类,使用super引用超类:

重写类的成员

子类可以覆盖实例方法,getterhe setter ,可以使用@overrider注释,

要在类型安全的代码中缩小方法参数或实例变量的类型,可以使用covariant关键字。

重写操作符

重写nosuchmethod方法来处理程序访问一个不存在的方法或成员变量

不能调用没有实现的方法,除非以下任何一个是正确的:

被调用者有静态方法dynamic,

被调用者有一个静态类型来定义未实现的方法(抽象的也可以),而接受者的动态类型有一个nosuchmethod()的实现,它与类对象的方法不同。

枚举类型

使用enum关键字声明枚举类型:

枚举中每个值都有一个索引getter,返回enum声明中值的从0开始的位置。

要获取枚举中所有值列表,可以使用enum的values常量。

可以在switch中使用enum,如果switch的case不处理enum所有值,会有一个警告信息。

枚举类型有以下限制:

不能子类化,混合或实现枚举

不能显式的实例化一个枚举

添加mixins特性:

mixin是在多个类层次结构中重用类代码的一种方式。

要使用mixin,请在with关键字后面加上一个或多个mixiin名称。

静态变量(类变量)实现类范围的变量和方法:注意,静态变量在使用之前不会初始化。

静态方法:静态方法(类方法)不对实例进行操作,因此无法访问该实例。注意:对于通用或广泛使用的实用程序和功能,考虑使用顶级函数,而不是静态方法。

可以使用静态方法作为编译时常量,例如,可以将静态方法作为参数传递给常量构造函数。

泛型:

泛型集合及其包含的类型:

dart通用类型被具体化,这意味着他们在运行时携带他们的类型信息。

相反,Java中泛型使用擦除。这意味着泛型类型参数在运行时被删除,在Java中,可以测试一个对象是否是一个列表,但不能测试是否是list.

限制参数化类型:

在实现泛型类型时,希望限制其参数类型,可以使用extends,也可以不指定泛型参数。

在这里,first上的泛型参数(<T>)允许你在很多地方使用类型参数T:

在函数的返回中返回类型(T)

在参数的类型中使用(List<T>)

在局部变量的类型中(T tmp)

库的可见性:

以下划线_开头的标识符仅在库里可见。每个dart应用程序都是一个库,即使它不使用库指令。

导入一个库需要提供库的URI,对于内置库,URI具有特定的形式。(dart:scheme),对于其他库,可以使用文件路径或者包:scheme的形式。

注意:URI表示统一资源标识符。url(统一资源定位器)是一种常见的URI。

指定一个库前缀

只导入库的一部分:

延迟加载:

允许应用在需要时按需加载库

异步支持:

dart 库中有非常多的函数返回Future对象或者stream对象,这些函数是异步的,在可能耗时的操作的语句之后不等到操作完成就返回。

async 和await 支持异步编程。

处理future:

当你需要一个完整的futures结果,

1,使用async和await

2,使用future api

使用try catch finally 来处理使用await中的错误:

可以在函数中多次使用awiait。

在await表达式中,表达式的值通常是一个future对象,如果不是,那么这个值将被包装成future,future对象指示返回结果一定是一个对象。表达式的值就是被返回的对象。await表达式会让程序执行挂起,知道返回对象可用。如果在使用await时出现编译时错误,请确保await在异步函数中,

注意,函数的主体不需要future api,如果需要,dart将创建future对象。如果函数没有返回有用的值,那么返回future<void>类型。

处理流:

当需要从stream获取值的时候

1,使用async异步for循环(await for)

2,使用stream api 

表达式的值必须是具有stream类型,

1,等待流发出值

2,执行for循环的主体,并将变量设置为发出的值

3,重复1,2,直到流关闭。

要停止监听流,可以使用break,或return,跳出for循环,并从流中取消订阅。

生成器:

当需要延迟的生成一个值的序列时,请考虑使用生成器函数,dart内置支持两种生成器函数。

1,同步生成器:返回itearable对象。

2,异步生成器:返回stream对象。

可调用的类:

隔离器:

在dart中,函数是对象,和字符串数字一样,typedf和funtion-type 为函数提供一个类型别名,可以在声明字段和返回类型时使用这个名称,当函数被分配给变量时,typedef保留类型信息。

当给compare分配f时类型信息会丢失。f的类型是(Object, Object)->int(int表示返回值类型),当然compare的类型是Function。如果我们更改代码以使用显式名称和保留类型信息,开发人员和工具都可以使用这些信息。

元数据

使用元数据提供关于代码的附加信息。元数据注释以字符@开头,后跟对编译时常量(如deprecated)的引用或对常量构造函数的调用。

所有Dart代码都可以使用两个注释:@deprecated和@override

也可以定义自己的元数据注释

元数据可以出现在库,类,类型定义,类型参数,构造函数,工厂,函数,字段,参数或变量之前,也可以出现在导入或导出指令之前,可以使用反射在运行时检索元数据。

文档注释:

Dart常用库:

1, print

2,numbers

3,字符串和正则表达式

映射map

集合类型的公共方法

尽管map没有实现itrable,但是可以使用map键值对属性获得。

URIs

Uri类提供了对字符串进行编码和解码的函数,以便在Uri中使用(您可能知道url)。这些函数处理uri特有的字符,例如&和=。Uri类还解析并公开Uri主机、端口、 协议等的组件。

日期和时间

实用程序类 包括排序、映射,迭代

实现map键

迭代

异常

异步 Future

多个异步

使用异步for循环

监听数据流

改变数据流

dart:convert库(API reference)为JSON和UTF-8提供了转换器,并且支持创建额外的转换器。JSON是一种表示结构化对象和集合的简单文本格式。UTF-8是一种常见的变宽编码,可以表示Unicode字符集中的每个字符

代码风格参考

库的使用

字符串的使用

集合

函数的使用

参数

变量

成员

构造函数

错误处理

异步

命名

库的设计

类的设计

构造函数

成员设计

类型设计

参数指南

代码示例

上一篇下一篇

猜你喜欢

热点阅读