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字符集中的每个字符
代码风格参考
库的使用
字符串的使用
集合
函数的使用
参数
变量
成员
构造函数
错误处理
异步
命名
库的设计
类的设计
构造函数
成员设计
类型设计
参数指南
代码示例
网友评论