Dart Programming - 快速指南
Dart Programming - Overview
Dart是一种面向对象的语言,具有C风格的语法,可以选择将其编译成JavaScript。 它支持各种编程辅助工具,如接口,类,集合,泛型和可选类型。
Dart可以广泛用于创建单页面应用程序。 单页应用程序仅适用于网站和Web应用程序。 单页面应用程序可以在网站的不同屏幕之间进行导航,而无需在浏览器中加载不同的网页。 一个典型的例子是GMail当您点击收件箱中的邮件时,浏览器会停留在同一网页上,但JavaScript代码会隐藏收件箱并将邮件正文显示在屏幕上。
谷歌发布了一个特殊版本的Chromium - Dart VM 。 使用Dartium意味着在准备好在其他浏览器上进行测试之前,您不必将代码编译为JavaScript。
下表比较了Dart和JavaScript的功能。
特征 | Dart | JavaScript |
---|---|---|
Type system | Optional, dynamic | Weak, dynamic |
Classes | Yes, single inheritance | Prototypical |
Interfaces | Yes, multiple interfaces | No |
Concurrency | Yes, with isolates | Yes, with HTML5 web workers |
本教程提供了对Dart编程语言的基本级别理解。
Dart Programming - Environment
本章讨论在Windows平台上为Dart设置执行环境。
使用DartPad在线执行脚本
您可以使用https://dartpad.dartlang.org/的在线编辑器在线测试您的脚本。 Dart编辑器执行脚本并显示HTML和控制台输出。 在线编辑器附带一组预设代码示例。
Dartpad编辑器的屏幕截图如下 -
Dartpad还能够以更严格的方式进行编码。 这可以通过检查编辑器右下角的强模式选项来实现。 强模式有助于 -
- 更强大的静态和动态检查
- 用于更好互操作性的惯用JavaScript代码生成。
您可以使用Dartpad尝试以下示例
void main() {
print('hello world');
}
代码将显示以下输出
hello world
设置本地环境
在本节中,让我们看看如何设置本地环境。
使用文本编辑器
一些编辑器的示例包括Windows Notepad,Notepad ++,Emacs,vim或vi等。编辑器可能因操作系统而异。 源文件通常以扩展名“.dart”命名。
安装Dart SDK
目前Dart的稳定版本是1.21.0 。 dart sdk可以从 - 下载 -
下面给出了Dart SDK安装的屏幕截图 -
完成SDK安装后,将PATH环境变量设置为 -
<dart-sdk-path>\bin
验证安装
要验证Dart是否已成功安装,请打开命令提示符并输入以下命令 -
Dart
如果安装成功,它将显示dart运行时。
IDE支持
许多IDE支持Dart中的脚本编写。 示例包括来自Jet大脑的Eclipse, IntelliJ和WebStorm 。
下面给出了使用WebStrom IDE配置Dart环境的步骤。
安装WebStorm
可以从https://www.jetbrains.com/webstorm/download/#section=windows-version.下载WebStorm的安装文件https://www.jetbrains.com/webstorm/download/#section=windows-version.
WebStorm安装文件适用于Mac OS,Windows和Linux。
下载安装文件后,请按照以下步骤操作 -
安装Dart SDK:请参阅上面列出的步骤
创建一个新的Dart项目并配置Dart支持
要创建一个新的Dart项目,
单击“欢迎”屏幕中的“ Create New Project ”
在下一个对话框中,单击“ Dart
如果没有为Dart SDK路径指定值,请提供SDK路径。 例如,SDK路径可以是《dart installation directory》/dart/dartsdk 。
将Dart文件添加到项目中
要将Dart文件添加到项目中 -
- 右键单击项目
- 新→Dart_programming文件
- 输入Dart脚本的名称
下面给出了WebStorm编辑器的屏幕截图 -
dart2js工具
dart2js工具将Dart代码编译为JavaScript。 将Dart代码编译为JS可以在不支持Dart VM的浏览器上运行Dart脚本。
dart2js工具作为Dart SDK的一部分提供,可以在/dartsdk/bin folder 。
要将Dart编译为JavaScript,请在终端中键入以下命令
dart2js - - out = <output_file>.js <dart_script>.dart
此命令生成一个文件,其中包含与Dart代码等效的JavaScript。 有关使用此实用程序的完整教程可在Dart官方网站上找到。
Dart Programming - Syntax
语法定义了一组用于编写程序的规则。 每种语言规范都定义了自己的语法。 Dart计划由 - 组成 -
- 变量和运算符
- Classes
- Functions
- 表达式和编程构造
- 决策和循环结构
- Comments
- Libraries and Packages
- Typedefs
- 数据结构表示为集合/泛型
你的第一个Dart_programming码
让我们从传统的“Hello World”示例开始 -
main() {
print("Hello World!");
}
main()函数是Dart中的预定义方法。 此方法充当应用程序的入口点。 Dart脚本需要main()方法来执行。 print()是一个预定义的函数,它将指定的字符串或值输出到标准输出,即终端。
上述代码的输出将是 -
Hello World!
执行Dart_programming计划
您可以通过两种方式执行Dart程序 -
- Via the terminal
- 通过WebStorm IDE
通过终端
通过终端执行Dart程序 -
- 导航到当前项目的路径
- 在“终端”窗口中键入以下命令
dart file_name.dart
通过WebStorm IDE
要通过WebStorm IDE执行Dart程序 -
右键单击IDE上的Dart脚本文件。 (该文件应包含main()函数以启用执行)
单击'Run 《file_name》'选项。 下面给出了相同的屏幕截图 -
可以选择点击 按钮或使用快捷键Ctrl+Shift+F10执行Dart脚本。
Dart Command-Line Options
Dart命令行选项用于修改Dart脚本执行。 Dart的常见命令行选项包括以下内容 -
Sr.No | 命令行选项和说明 |
---|---|
1 | -c or --c 启用断言和类型检查(选中模式)。 |
2 | --version 显示VM版本信息。 |
3 | --packages <path> 指定程序包解析配置文件的路径。 |
4 | -p <path> 指定在何处查找导入的库。 此选项不能与--packages一起使用。 |
5 | -h or --help 显示帮助。 |
启用检查模式
Dart_programming程序以两种模式运行,即 -
- 检查模式
- 生产模式(默认)
建议在开发和测试期间以checked mode运行Dart VM,因为它会添加警告和错误以帮助开发和调试过程。 选中的模式会强制执行各种检查,例如类型检查等。要打开选中的模式,请在运行脚本时在脚本文件名之前添加-c或--checked选项。
但是,为了在运行脚本时确保性能优势,建议在production mode运行脚本。
考虑以下Test.dart脚本文件 -
void main() {
int n = "hello";
print(n);
}
输入以下命令运行脚本 -
dart Test.dart
虽然存在类型不匹配,但在关闭检查模式时脚本会成功执行。 该脚本将产生以下输出 -
hello
现在尝试使用“ - - checked”或“-c”选项执行脚本 -
dart -c Test.dart
要么,
dart - - checked Test.dart
Dart VM将抛出错误,指出存在类型不匹配。
Unhandled exception:
type 'String' is not a subtype of type 'int' of 'n' where
String is from dart:core
int is from dart:core
#0 main (file:///C:/Users/Administrator/Desktop/test.dart:3:9)
#1 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart :261)
#2 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)
Dart中的标识符
标识符是给予程序中元素的名称,如变量,函数等。标识符的规则是 -
标识符可以包括字符和数字。 但是,标识符不能以数字开头。
除下划线(_)或美元符号($)外,标识符不能包含特殊符号。
标识符不能是关键字。
它们必须是独一无二的
标识符区分大小写。
标识符不能包含空格。
下表列出了有效和无效标识符的几个示例 -
有效标识符 | 标识符无效 |
---|---|
firstName | Var |
first_name | first name |
num1 | first-name |
$result | 1number |
Dart中的关键字
关键词在语言的上下文中具有特殊含义。 下表列出了Dart中的一些关键字。
摘要1 | continue | false | new | this |
as 1 | default | final | null | throw |
assert | deferred 1 | finally | operator 1 | true |
async 2 | do | for | part 1 | try |
async * 2 | dynamic 1 | get 1 | rethrow | typedef 1 |
await 2 | else | if | return | var |
break | enum | implements 1 | set 1 | void |
case | export 1 | import 1 | static 1 | while |
catch | external 1 | in | super | with |
class | extends | is | switch | yield 2 |
const | factory 1 | library 1 | sync* 2 | yield* 2 |
空白和换行
Dart忽略程序中出现的空格,制表符和换行符。 您可以在程序中自由使用空格,制表符和换行符,并且可以自由地以简洁一致的方式格式化和缩进程序,使代码易于阅读和理解。
Dart是区分大小写的
Dart区分大小写。 这意味着Dart区分大写和小写字符。
声明以分号结尾
每行指令都称为语句。 每个dart语句必须以分号(;)结尾。 单行可以包含多个语句。 但是,这些语句必须用分号分隔。
评论Dart
注释是提高程序可读性的一种方法。 注释可用于包含有关程序的其他信息,如代码的作者,有关函数/构造的提示等。编译器会忽略注释。
Dart支持以下类型的评论 -
Single-line comments ( // ) - “//”和行尾之间的任何文本都被视为注释
Multi-line comments (/* */) - 这些注释可能跨越多行。
例子 (Example)
// this is single line comment
/* This is a
Multi-line comment
*/
Dart中面向对象的编程
Dart是一种面向对象的语言。 面向对象是一种遵循真实世界建模的软件开发范例。 Object Orientation将程序视为通过称为方法的机制相互通信的对象集合。
Object - 对象是任何实体的实时表示。 根据Grady Brooch,每个对象必须具有三个功能 -
State - 由对象的属性描述。
Behavior - 描述对象的行为方式。
Identity - 将对象与一组类似此类对象区分开的唯一值。
Class - OOP方面的类是创建对象的蓝图。 类封装了对象的数据。
Method - 方法促进对象之间的通信。
示例:Dart和Object Orientation
class TestClass {
void disp() {
print("Hello World");
}
}
void main() {
TestClass c = new TestClass();
c.disp();
}
上面的示例定义了一个类TestClass 。 该类有一个方法disp() 。 该方法在终端上打印字符串“Hello World”。 new关键字创建类的对象。 该对象调用方法disp() 。
代码应该产生以下output -
Hello World
Dart Programming - Data Types
编程语言最基本的特征之一是它支持的数据类型集。 这些是可以用编程语言表示和操作的值的类型。
Dart语言支持以下类型 -
- Numbers
- Strings
- Booleans
- Lists
- Maps
Numbers
Dart中的数字用于表示数字文字。 Number Dart有两种口味 -
Integer - 整数值表示非小数值,即没有小数点的数值。 例如,值“10”是整数。 整数文字使用int关键字表示。
Double - Dart还支持小数数值,即带小数点的值。 Dart中的Double数据类型表示64位(双精度)浮点数。 例如,值“10.10”。 关键字double用于表示浮点文字。
Strings
字符串代表一系列字符。 例如,如果要存储一些数据,如名称,地址等,则应使用字符串数据类型。 Dart字符串是一系列UTF-16代码单元。 Runes用于表示UTF-32代码单元序列。
关键字String用于表示字符串文字。 字符串值嵌入单引号或双引号中。
Boolean
布尔数据类型表示布尔值true和false。 Dart使用bool关键字表示布尔值。
List and Map
数据类型列表和映射用于表示对象的集合。 List是一组有序的对象。 Dart中的List数据类型与其他编程语言中的数组概念同义。 Map数据类型将一组值表示为键值对。 dart: core库可以分别通过预定义的List和Map类创建和操作这些集合。
动态类型
Dart是一种可选的键入语言。 如果未明确指定变量的类型,则变量的类型是dynamic 。 dynamic关键字也可以显式用作类型注释。
Dart Programming - Variables
变量是“存储器中的命名空间”,用于存储值。 换句话说,它作为程序中值的容器。 变量名称称为标识符。 以下是标识符的命名规则 -
标识符不能是关键字。
标识符可以包含字母和数字。
标识符不能包含空格和特殊字符,但下划线(_)和美元($)符号除外。
变量名称不能以数字开头。
键入语法
必须在使用变量之前声明变量。 Dart使用var关键字来实现相同的目标。 声明变量的语法如下所示 -
var name = 'Smith';
dart中的所有变量都存储对该值的引用,而不是包含该值。 名为name的变量包含对String对象的引用,其值为“Smith”。
Dart通过在变量名前加上数据类型来支持type-checking 。 类型检查可确保变量仅包含特定于数据类型的数据。 下面给出了相同的语法 -
String name = 'Smith';
int num = 10;
考虑以下示例 -
void main() {
String name = 1;
}
上面的代码段将导致警告,因为分配给变量的值与变量的数据类型不匹配。
输出 (Output)
Warning: A value of type 'String' cannot be assigned to a variable of type 'int'
所有未初始化的变量的初始值为null。 这是因为Dart将所有值都视为对象。 以下示例说明了相同的情况 -
void main() {
int num;
print(num);
}
输出 (Output)
Null
动态关键字
声明没有静态类型的变量被隐式声明为动态。 也可以使用dynamic关键字代替var关键字声明变量。
以下示例说明了相同的内容。
void main() {
dynamic x = "tom";
print(x);
}
输出 (Output)
tom
决赛和Const
final和const关键字用于声明常量。 Dart阻止修改使用final或const关键字声明的变量的值。 这些关键字可以与变量的数据类型一起使用,也可以与var关键字一起使用。
const关键字用于表示编译时常量。 使用const关键字声明的变量是隐式最终的。
语法:final关键字
final variable_name
OR
final data_type variable_name
语法:const关键字
const variable_name
OR
const data_type variable_name
示例 - 最终关键字
void main() {
final val1 = 12;
print(val1);
}
输出 (Output)
12
示例 - const关键字
void main() {
const pi = 3.14;
const area = pi*12*12;
print("The output is ${area}");
}
上面的例子使用const关键字声明了两个常量pi和area 。 area变量的值是编译时常量。
输出 (Output)
The output is 452.15999999999997
Note - 只有const变量可用于计算编译时常量。 编译时常量是常量,其值将在编译时确定
例子 (Example)
如果尝试修改使用final或const关键字声明的变量,Dart会抛出异常。 下面给出的例子说明了相同的 -
void main() {
final v1 = 12;
const v2 = 13;
v2 = 12;
}
上面给出的代码将抛出以下错误作为output -
Unhandled exception:
cannot assign to final variable 'v2='.
NoSuchMethodError: cannot assign to final variable 'v2='
#0 NoSuchMethodError._throwNew (dart:core-patch/errors_patch.dart:178)
#1 main (file: Test.dart:5:3)
#2 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:261)
#3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)
Dart Programming - Operators
表达式是一种特殊类型的语句,它计算为一个值。 每个表达都由 -
Operands - 表示数据
Operator - 定义如何处理操作数以生成值。
考虑以下表达式 - “2 + 3”。 在该表达式中,2和3是operands ,符号“+”(加号)是operator 。
在本章中,我们将讨论Dart中可用的运算符。
- 算术运算符
- 平等和关系运算符
- 键入测试运算符
- 按位运算符
- 分配运算符
- 逻辑运算符
算术运算符 (Arithmetic Operators)
下表显示了Dart支持的算术运算符。
Sr.No | 经营者和意义 |
---|---|
1 | + 加 |
2 | − 减去 |
3 | -expr 一元减号,也称为否定(反转表达式的符号) |
4 | * 乘 |
5 | / 划分 |
6 | ~/ 除以,返回整数结果 |
7 | % 获取整数除法的余数(模数) |
8 | ++ 增量 |
9 | -- 递减 |
平等和关系运算符
关系运算符测试或定义两个实体之间的关系类型。 关系运算符返回一个布尔值,即true/false。
假设A的值为10,B为20。
操作者 | 描述 | 例 |
---|---|---|
> | Greater than | (A> B)是假的 |
< | Lesser than | (A < B) 为真 |
>= | 大于或等于 | (A> = B)为假 |
<= | 小于或等于 | (A <= B)为真 |
== | Equality | (A == B)是真的 |
!= | 不相等 | (A!= B)是真的 |
键入测试运算符
这些运算符在运行时检查类型很方便。
操作者 | 含义 |
---|---|
is | 如果对象具有指定的类型,则为True |
is! | 如果对象具有指定的类型,则返回false |
按位运算符 (Bitwise Operators)
下表列出了Dart中可用的按位运算符及其作用 -
操作者 | 描述 | 例 |
---|---|---|
Bitwise AND | a&b | 返回每个位位置的一个,两个操作数的相应位为1。 |
Bitwise OR | 一个| b | 在每个位的位置返回一个,其中一个或两个操作数的相应位是1。 |
Bitwise XOR | a ^ b | 在每个位位置返回一个,其中任一个但不是两个操作数的相应位都是1。 |
Bitwise NOT | ~a | 反转其操作数的位。 |
Left shift | a ≪ b | 将二进制表示b(<32)位向左移位,从右移零。 |
Signpropagating right shift | a»b | 将二进制表示b(<32)位向右移位,丢弃移位的位。 |
赋值操作符 (Assignment Operators)
下表列出了Dart中可用的赋值运算符。
Sr.No | 操作符和说明 |
---|---|
1 | =(Simple Assignment ) 将值从右侧操作数分配给左侧操作数 Ex :C = A + B将A + B的值分配给C |
2 | ??= 仅当变量为null时才分配值 |
3 | +=(Add and Assignment) 它将右操作数添加到左操作数并将结果赋给左操作数。 Ex :C + = A等于C = C + A. |
4 | ─=(Subtract and Assignment) 它从左操作数中减去右操作数,并将结果赋给左操作数。 Ex :C - = A相当于C = C - A. |
5 | *=(Multiply and Assignment) 它将右操作数与左操作数相乘,并将结果赋给左操作数。 Ex :C * = A等于C = C * A. |
6 | /=(Divide and Assignment) 它将左操作数与右操作数分开,并将结果赋给左操作数。 |
Note - 相同的逻辑适用于Bitwise运算符,因此它们将变为«=,»=,»=,»=,| =和^ =。
逻辑运算符 (Logical Operators)
逻辑运算符用于组合两个或多个条件。 逻辑运算符返回一个布尔值。 假设变量A的值为10,B为20。
操作者 | 描述 | 例 |
---|---|---|
&& | And - 仅当指定的所有表达式都返回true时,运算符才返回true | (A> 10 && B> 10)是假的。 |
|| | OR - 如果指定的至少一个表达式返回true,则运算符返回true | (A> 10 || B> 10)是真的。 |
! | NOT - 运算符返回表达式结果的反函数。 例如:!(7“5)返回false | !(A> 10)是真的。 |
条件表达式
Dart有两个运算符,可以让你评估可能需要ifelse语句的表达式 -
条件? expr1:expr2
如果condition为true,则表达式计算expr1 (并返回其值); 否则,它会计算并返回expr2的值。
expr1 ?? 表达式2
如果expr1为非null,则返回其值; 否则,计算并返回expr2的值
例子 (Example)
以下示例显示如何在Dart中使用条件表达式 -
void main() {
var a = 10;
var res = a > 12 ? "value greater than 10":"value lesser than or equal to 10";
print(res);
}
它将产生以下输出 -
value lesser than or equal to 10
例子 (Example)
让我们再看一个例子 -
void main() {
var a = null;
var b = 12;
var res = a ?? b;
print(res);
}
它将产生以下输出 -
12
Dart Programming - Loops
有时,某些指令需要重复执行。 循环是一种理想的方法。 循环表示必须重复的一组指令。 在循环的上下文中,重复被称为iteration 。
下图说明了循环的分类 -
让我们开始讨论Definite Loops。 迭代次数是确定/固定的definite loop称为definite loop 。
Sr.No | 循环和描述 |
---|---|
1 | for循环 for循环是一个确定循环的实现。 for循环执行代码块指定的次数。 它可用于迭代一组固定的值,例如数组 |
2 | for ... in循环 for ... in循环用于循环对象的属性。 |
继续,让我们现在讨论无限循环。 当循环中的迭代次数不确定或未知时,将使用不定循环。 可以使用以下方式实现无限循环:
Sr.No | 循环和描述 |
---|---|
1 | while循环 每次指定的条件求值为true时,while循环都会执行指令。 换句话说,循环在执行代码块之前评估条件。 |
2 | do…while循环 do ... while循环类似于while循环,只是do ... while循环不会在第一次循环执行时评估条件。 |
现在让我们继续讨论Dart的Loop Control Statements 。
Sr.No | 控制声明和描述 |
---|---|
1 | break语句 break语句用于将控件从构造中取出。 在循环中使用break会导致程序退出循环。 以下是break语句的示例。 |
2 | continue语句 continue语句跳过当前迭代中的后续语句,并将控制权带回循环的开头。 |
使用标签来控制流量
label只是一个标识符,后跟冒号(:),应用于语句或代码块。 标签可以与break一起使用并continue更精确地控制流量。
'continue'或'break'语句与其标签名称之间不允许换行。 此外,标签名称和关联循环之间不应该有任何其他语句。
示例:带有Break的标签
void main() {
outerloop: // This is the label name
for (var i = 0; i < 5; i++) {
print("Innerloop: ${i}");
innerloop:
for (var j = 0; j < 5; j++) {
if (j > 3 ) break ;
// Quit the innermost loop
if (i == 2) break innerloop;
// Do the same thing
if (i == 4) break outerloop;
// Quit the outer loop
print("Innerloop: ${j}");
}
}
}
成功执行上述代码后,将显示以下output 。
Innerloop: 0
Innerloop: 0
Innerloop: 1
Innerloop: 2
Innerloop: 3
Innerloop: 1
Innerloop: 0
Innerloop: 1
Innerloop: 2
Innerloop: 3
Innerloop: 2
Innerloop: 3
Innerloop: 0
Innerloop: 1
Innerloop: 2
Innerloop: 3
Innerloop: 4
示例:带继续的标签
void main() {
outerloop: // This is the label name
for (var i = 0; i < 3; i++) {
print("Outerloop:${i}");
for (var j = 0; j < 5; j++) {
if (j == 3){
continue outerloop;
}
print("Innerloop:${j}");
}
}
}
成功执行上述代码后,将显示以下输出。
Outerloop: 0
Innerloop: 0
Innerloop: 1
Innerloop: 2
Outerloop: 1
Innerloop: 0
Innerloop: 1
Innerloop: 2
Outerloop: 2
Innerloop: 0
Innerloop: 1
Innerloop: 2
Dart Programming - Decision Making
条件/决策构造在执行指令之前评估条件。
Dart中的条件结构分类在下表中。
Sr.No | 声明和说明 |
---|---|
1 | if statement if语句由一个布尔表达式后跟一个或多个语句组成。 |
2 | If...Else 语句 if后面可以跟一个可选的else块。 if块测试的布尔表达式求值为false, if执行else块。 |
3 | else…if Ladder else…if ladder可用于测试多个条件。 以下是相同的语法。 |
4 | switch…case 语句 switch语句计算表达式,将表达式的值与case子句匹配,并执行与该case相关的语句。 |
Dart Programming - Numbers
Dart_programming数字可归类为 -
int - 任意大小的整数。 int数据类型用于表示整数。
double -64位(双精度)浮点数,由IEEE 754标准规定。 double数据类型用于表示小数
num类型由int和double类型继承。 dart core library允许对数值进行大量操作。
声明数字的语法如下 -
int var_name; // declares an integer variable
double var_name; // declares a double variable
例子 (Example)
void main() {
int num1 = 10;
// declare an integer
double num2 = 10.50;
// declare a double value
print(num1);
print(num2);
}
它将产生以下输出 -
10
10.5
Note - 如果将小数值分配给整数变量, Dart VM将抛出异常。
Parsing
parse()静态函数允许将包含数字文字的字符串解析为数字。 下图说明了相同的情况 -
void main() {
print(num.parse('12'));
print(num.parse('10.91'));
}
上面的代码将导致以下输出 -
12
10.91
如果传递除数字以外的任何值,则解析函数抛出FormatException 。 以下代码显示如何将字母数字值传递给parse()函数。
例子 (Example)
void main() {
print(num.parse('12A'));
print(num.parse('AAAA'));
}
上面的代码将导致以下输出 -
Unhandled exception:
FormatException: 12A
#0 num.parse (dart:core/num.dart:446)
#1 main (file:///D:/Demos/numbers.dart:4:13)
#2 _startIsolate.<anonymous closure> (dart:isolatepatch/isolate_patch.dart:261)
#3 _RawReceivePortImpl._handleMessage (dart:isolatepatch/isolate_patch.dart:148)
数字属性
下表列出了Dart编号支持的属性。
Sr.No | 财产和描述 |
---|---|
1 | hashcode 返回数值的哈希码。 |
2 | isFinite 如果数字有限,则为真; 否则,是的。 |
3 | isInfinite 如果数字为正无穷大或负无穷大,则为真; 否则,是的。 |
4 | isNan 如果数字是双重非数字值,则为真; 否则,是的。 |
5 | isNegative 如果数字为负,则为真; 否则,是的。 |
6 | sign 返回减一,零或加一,具体取决于数字的符号和数值。 |
7 | isEven 如果数字是偶数,则返回true。 |
8 | isOdd 如果数字是奇数,则返回true。 |
Number Methods
以下是数字支持的常用方法列表 -
Sr.No | 方法和描述 |
---|---|
1 | abs 返回数字的绝对值。 |
2 | ceil 返回不小于该数字的最小整数。 |
3 | compareTo 将此与其他数字进行比较。 |
4 | Floor 返回不大于当前数字的最大整数。 |
5 | remainder 在分割两个数字后返回截断的余数。 |
6 | Round 返回最接近当前数字的整数。 |
7 | toDouble 返回数字的等效值的两倍。 |
8 | toInt 返回该数字的等效整数。 |
9 | toString 返回数字的字符串等效表示形式。 |
10 | truncate 丢弃任何小数位后返回一个整数。 |
Dart Programming - String
String数据类型表示一系列字符。 Dart字符串是一系列UTF 16代码单元。
Dart中的字符串值可以使用单引号或双引号或三引号表示。 单行字符串使用单引号或双引号表示。 三引号用于表示多行字符串。
在Dart中表示字符串值的语法如下所示 -
语法 (Syntax)
String variable_name = 'value'
OR
String variable_name = ''value''
OR
String variable_name = '''line1
line2'''
OR
String variable_name= ''''''line1
line2''''''
以下示例说明了在Dart中使用String数据类型。
void main() {
String str1 = 'this is a single line string';
String str2 = "this is a single line string";
String str3 = '''this is a multiline line string''';
String str4 = """this is a multiline line string""";
print(str1);
print(str2);
print(str3);
print(str4);
}
它将产生以下Output -
this is a single line string
this is a single line string
this is a multiline line string
this is a multiline line string
字符串是不可变的。 但是,字符串可以进行各种操作,结果字符串可以存储为新值。
字符串插值
通过将值附加到静态字符串来创建新字符串的过程称为concatenation或interpolation 。 换句话说,它是将字符串添加到另一个字符串的过程。
运算符加(+)是连接/插入字符串的常用机制。
例子1 (Example 1)
void main() {
String str1 = "hello";
String str2 = "world";
String res = str1+str2;
print("The concatenated string : ${res}");
}
它将产生以下output -
The concatenated string : Helloworld
例子2 (Example 2)
您可以使用“$ {}”来插入字符串中Dart表达式的值。 以下示例说明了相同的内容。
void main() {
int n=1+1;
String str1 = "The sum of 1 and 1 is ${n}";
print(str1);
String str2 = "The sum of 2 and 2 is ${2+2}";
print(str2);
}
它将产生以下output -
The sum of 1 and 1 is 2
The sum of 2 and 2 is 4
字符串属性
下表中列出的属性都是只读的。
Sr.No | 财产和描述 |
---|---|
1 | codeUnits 返回此字符串的UTF-16代码单元的不可修改列表。 |
2 | isEmpty 如果此字符串为空,则返回true。 |
3 | Length 返回字符串的长度,包括空格,制表符和换行符。 |
操纵字符串的方法
dart: core library的String类还提供了操作字符串的方法。 其中一些方法如下 -
Sr.No | 方法和描述 |
---|---|
1 | toLowerCase() 将此字符串中的所有字符转换为小写。 |
2 | toUpperCase() 将此字符串中的所有字符转换为大写。 |
3 | trim() 返回没有任何前导和尾随空格的字符串。 |
4 | compareTo() 将此对象与另一对象进行比较。 |
5 | replaceAll() 用给定值替换与指定模式匹配的所有子字符串。 |
6 | split() 在指定分隔符的匹配处拆分字符串并返回子字符串列表。 |
7 | substring() 返回此字符串的子字符串,该字符串从startIndex(包括)延伸到endIndex,exclusive。 |
8 | toString() 返回此对象的字符串表示形式。 |
9 | codeUnitAt() 返回给定索引处的16位UTF-16代码单元。 |
Dart Programming - Boolean
Dart为布尔数据类型提供内置支持。 DART中的布尔数据类型仅支持两个值 - true和false。 关键字bool用于表示DART中的布尔文字。
在DART中声明布尔变量的语法如下所示 -
bool var_name = true;
OR
bool var_name = false
例子 (Example)
void main() {
bool test;
test = 12 > 5;
print(test);
}
它将产生以下output -
true
例子 (Example)
与JavaScript不同,布尔数据类型仅将文字true识别为true。 任何其他值都被视为false。 考虑以下示例 -
var str = 'abc';
if(str) {
print('String is not empty');
} else {
print('Empty String');
}
如果在JavaScript中运行,上面的代码段将打印消息“String is not empty”,因为如果字符串不为空,if结构将返回true。
但是,在Dart中, str被转换为false as str != true 。 因此,代码段将打印消息'Empty String' (在未选中模式下运行时)。
例子 (Example)
如果以checked模式运行,上面的代码片段将引发异常。 同样如下图所示 -
void main() {
var str = 'abc';
if(str) {
print('String is not empty');
} else {
print('Empty String');
}
}
它将在Checked Mode产生以下output -
Unhandled exception:
type 'String' is not a subtype of type 'bool' of 'boolean expression' where
String is from dart:core
bool is from dart:core
#0 main (file:///D:/Demos/Boolean.dart:5:6)
#1 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:261)
#2 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)
它将以Unchecked Mode生成以下output -
Empty String
Note - 默认情况下, WebStorm IDE以选中模式运行。
Dart Programming - Lists
编程中非常常用的集合是一个array 。 Dart以List对象的形式表示数组。 List只是一组有序的对象。 dart:core库提供了List类,可以创建和操作列表。
Dart中列表的逻辑表示如下 -
test_list - 是引用集合的标识符。
该列表包含值12,13和14.保存这些值的存储块称为elements 。
List中的每个元素都由一个称为index的唯一编号标识。 索引zero并向上扩展到n-1 ,其中n是List中元素的总数。 该索引也称为subscript 。
列表可分为 -
- Fixed Length List
- Growable List
现在让我们详细讨论这两种类型的lists 。
固定长度列表
固定长度列表的长度在运行时不能更改。 创建固定长度列表的语法如下所示 -
Step 1 − Declaring a list
声明固定长度列表的语法如下 -
var list_name = new List(initial_size)
上面的语法创建了指定大小的列表。 列表不能在运行时增长或缩小。 任何调整列表大小的尝试都将导致异常。
Step 2 − Initializing a list
初始化列表的语法如下所示 -
lst_name[index] = value;
例子 (Example)
void main() {
var lst = new List(3);
lst[0] = 12;
lst[1] = 13;
lst[2] = 11;
print(lst);
}
它将产生以下output -
[12, 13, 11]
可增长的清单
可增长列表的长度可以在运行时更改。 声明和初始化可增长列表的语法如下所示 -
Step 1 − Declaring a List
var list_name = [val1,val2,val3]
--- creates a list containing the specified values
OR
var list_name = new List()
--- creates a list of size zero
Step 2 − Initializing a List
index/subscript用于引用应该用值填充的元素。 初始化列表的语法如下所示 -
list_name[index] = value;
例子 (Example)
以下示例显示如何创建3个元素的列表。
void main() {
var num_list = [1,2,3];
print(num_list);
}
它将产生以下output -
[1, 2, 3]
例子 (Example)
以下示例使用empty List() constructor创建零长度列表。 List类中的add()函数用于动态地向列表中添加元素。
void main() {
var lst = new List();
lst.add(12);
lst.add(13);
print(lst);
}
它将产生以下output -
[12, 13]
列表属性
下表列出了dart:core library List类的一些常用属性。
Sr.No | 方法和描述 |
---|---|
1 | first 返回第一个元素大小写。 |
2 | isEmpty 如果集合没有元素,则返回true。 |
3 | isNotEmpty 如果集合至少包含一个元素,则返回true。 |
4 | length 返回列表的大小。 |
5 | last 返回列表中的最后一个元素。 |
6 | reversed 以相反顺序返回包含列表值的可迭代对象。 |
7 | Single 检查列表是否只有一个元素并返回它。 |
Dart Programming - Lists (Basic Operations)
在本章中,我们将讨论如何对列表执行一些基本操作,例如 -
Sr.No | 基本操作和说明 |
---|---|
1 | 将元素插入列表 可变列表可以在运行时动态增长。 List.add()函数将指定的值附加到List的末尾并返回修改后的List对象。 |
2 | 更新列表 Dart中的列表可以通过以下方式更新 - |
3 | 删除列表项 dart:core库中List类支持的以下函数可用于删除List中的项目。 |
Dart Programming - Map
Map对象是一个简单的键/值对。 地图中的键和值可以是任何类型。 地图是动态集合。 换句话说,Maps可以在运行时增长和缩小。
可以通过两种方式声明地图 -
- 使用地图文字
- 使用Map构造函数
使用地图文字声明地图
要使用地图文字声明地图,您需要将键值对括在一对花括号"{ }" 。
这是它的syntax -
var identifier = { key1:value1, key2:value2 [,…..,key_n:value_n] }
使用Map构造器声明Map
要使用Map构造函数声明Map,我们有两个步骤。 首先,声明地图,然后初始化地图。
declare a map的syntax如下 -
var identifier = new Map()
现在,使用以下语法initialize the map -
map_name[key] = value
示例:Map Literal
void main() {
var details = {'Usrname':'tom','Password':'pass@123'};
print(details);
}
它将产生以下output -
{Usrname: tom, Password: pass@123}
示例:在运行时向映射文字添加值
void main() {
var details = {'Usrname':'tom','Password':'pass@123'};
details['Uid'] = 'U1oo1';
print(details);
}
它将产生以下output -
{Usrname: tom, Password: pass@123, Uid: U1oo1}
示例:Map构造函数
void main() {
var details = new Map();
details['Usrname'] = 'admin';
details['Password'] = 'admin@123';
print(details);
}
它将产生以下output -
{Usrname: admin, Password: admin@123}
Note - 地图值可以是包括NULL的任何对象。
地图 - 属性
dart:core包中的Map类定义了以下属性 -
Sr.No | 财产和描述 |
---|---|
1 | Keys 返回表示键的可迭代对象 |
2 | Values 返回表示值的可迭代对象 |
3 | Length 返回Map的大小 |
4 | isEmpty 如果Map是空Map,则返回true |
5 | isNotEmpty 如果Map是空Map,则返回true |
Map - 函数
以下是在Dart中操作Maps的常用函数。
Sr.No | 功能名称和描述 |
---|---|
1 | addAll() 向此映射添加其他所有键值对。 |
2 | clear() 从地图中删除所有对。 |
3 | remove() 从地图中删除键及其关联值(如果存在)。 |
4 | forEach() 将f应用于地图的每个键值对。 |
Dart Programming - Symbol
Dart中的符号是不透明的动态字符串名称,用于反映库中的元数据。 简而言之,符号是一种存储人类可读字符串与优化供计算机使用的字符串之间关系的方法。
Reflection是一种在运行时获取类型元数据的机制,如类中的方法数,它具有的构造函数数或函数中的参数数。 您甚至可以调用在运行时加载的类型的方法。
在Dart反射中, dart:mirrors包中提供了特定的类。 此库适用于Web应用程序和命令行应用程序。
语法 (Syntax)
Symbol obj = new Symbol('name');
// expects a name of class or function or library to reflect
该name必须是有效的公共Dart成员名称,公共构造函数名称或库名称。
例子 (Example)
请考虑以下示例。 代码在库foo_lib声明了一个类Foo 。 该类定义方法m1, m2,和m3 。
Foo.dart
library foo_lib;
// libarary name can be a symbol
class Foo {
// class name can be a symbol
m1() {
// method name can be a symbol
print("Inside m1");
}
m2() {
print("Inside m2");
}
m3() {
print("Inside m3");
}
}
以下代码在Symbol类型的帮助下加载Foo.dart库并搜索Foo类。 由于我们反映了上述库中的元数据,因此代码导入了dart:mirrors库。
FooSymbol.dart
import 'dart:core';
import 'dart:mirrors';
import 'Foo.dart';
main() {
Symbol lib = new Symbol("foo_lib");
//library name stored as Symbol
Symbol clsToSearch = new Symbol("Foo");
// class name stored as Symbol
if(checkIf_classAvailableInlibrary(lib, clsToSearch))
// searches Foo class in foo_lib library
print("class found..");
}
bool checkIf_classAvailableInlibrary(Symbol libraryName, Symbol className) {
MirrorSystem mirrorSystem = currentMirrorSystem();
LibraryMirror libMirror = mirrorSystem.findLibrary(libraryName);
if (libMirror != null) {
print("Found Library");
print("checkng...class details..");
print("No of classes found is : ${libMirror.declarations.length}");
libMirror.declarations.forEach((s, d) => print(s));
if (libMirror.declarations.containsKey(className)) return true;
return false;
}
}
注意行libMirror.declarations.forEach((s,d)=> print(s)); 将在运行时迭代库中的每个声明,并将声明打印为Symbol类型。
此代码应产生以下output -
Found Library
checkng...class details..
No of classes found is : 1
Symbol("Foo") // class name displayed as symbol
class found.
示例:显示类的实例方法数
现在让我们考虑在类中显示实例方法的数量。 预定义的类ClassMirror帮助我们实现相同的目标。
import 'dart:core';
import 'dart:mirrors';
import 'Foo.dart';
main() {
Symbol lib = new Symbol("foo_lib");
Symbol clsToSearch = new Symbol("Foo");
reflect_InstanceMethods(lib, clsToSearch);
}
void reflect_InstanceMethods(Symbol libraryName, Symbol className) {
MirrorSystem mirrorSystem = currentMirrorSystem();
LibraryMirror libMirror = mirrorSystem.findLibrary(libraryName);
if (libMirror != null) {
print("Found Library");
print("checkng...class details..");
print("No of classes found is : ${libMirror.declarations.length}");
libMirror.declarations.forEach((s, d) => print(s));
if (libMirror.declarations.containsKey(className)) print("found class");
ClassMirror classMirror = libMirror.declarations[className];
print("No of instance methods found is ${classMirror.instanceMembers.length}");
classMirror.instanceMembers.forEach((s, v) => print(s));
}
}
此代码应产生以下output -
Found Library
checkng...class details..
No of classes found is : 1
Symbol("Foo")
found class
No of instance methods found is 8
Symbol("==")
Symbol("hashCode")
Symbol("toString")
Symbol("noSuchMethod")
Symbol("runtimeType")
Symbol("m1")
Symbol("m2")
Symbol("m3")
将符号转换为字符串
您可以使用MirrorSystem类将存储在符号中的类或类的名称转换回字符串。 以下代码显示了如何将符号转换为字符串。
import 'dart:mirrors';
void main(){
Symbol lib = new Symbol("foo_lib");
String name_of_lib = MirrorSystem.getName(lib);
print(lib);
print(name_of_lib);
}
它应该产生以下output -
Symbol("foo_lib")
foo_lib
Dart Programming - Runes
字符串是一系列字符。 Dart将字符串表示为Unicode UTF-16代码单元序列。 Unicode是一种格式,用于为每个字母,数字和符号定义唯一的数值。
由于Dart字符串是一系列UTF-16代码单元,因此字符串中的32位Unicode值使用特殊语法表示。 rune是表示Unicode代码点的整数。
dart:core库中的String类提供了访问runes机制。 可以通过三种方式访问字符串代码单元/符文 -
- 使用String.codeUnitAt()函数
- 使用String.codeUnits属性
- 使用String.runes属性
String.codeUnitAt() Function
可以通过索引访问字符串中的代码单元。 返回给定索引处的16位UTF-16代码单元。
语法 (Syntax)
String.codeUnitAt(int index);
例子 (Example)
import 'dart:core';
void main(){
f1();
}
f1() {
String x = 'Runes';
print(x.codeUnitAt(0));
}
它将产生以下output -
82
String.codeUnits Property
此属性返回指定字符串的UTF-16代码单元的不可修改列表。
语法 (Syntax)
String. codeUnits;
例子 (Example)
import 'dart:core';
void main(){
f1();
}
f1() {
String x = 'Runes';
print(x.codeUnits);
}
它将产生以下output -
[82, 117, 110, 101, 115]
String.runes Property
此属性返回此string.Runes的可迭代Unicode代码点string.Runes可迭代扩展。
语法 (Syntax)
String.runes
例子 (Example)
void main(){
"A string".runes.forEach((int rune) {
var character=new String.fromCharCode(rune);
print(character);
});
}
它将产生以下output -
A
s
t
r
i
n
g
Unicode代码点通常表示为\uXXXX ,其中XXXX是4位十六进制值。 要指定多于或少于4个十六进制数字,请将值放在大括号中。 可以在dart:core库中使用Runes类的构造函数。
例子 (Example)
main() {
Runes input = new Runes(' \u{1f605} ');
print(new String.fromCharCodes(input));
}
它将产生以下output -
Dart Programming - Enumeration
枚举用于定义命名常量值。 使用enum关键字声明枚举类型。
语法 (Syntax)
enum enum_name {
enumeration list
}
Where,
- enum_name指定枚举类型名称
- enumeration list是以逗号分隔的标识符列表
枚举列表中的每个符号代表一个整数值,一个大于它之前的符号。 默认情况下,第一个枚举符号的值为0。
例如 (For example)
enum Status {
none,
running,
stopped,
paused
}
例子 (Example)
enum Status {
none,
running,
stopped,
paused
}
void main() {
print(Status.values);
Status.values.forEach((v) => print('value: $v, index: ${v.index}'));
print('running: ${Status.running}, ${Status.running.index}');
print('running index: ${Status.values[1]}');
}
它将产生以下output -
[Status.none, Status.running, Status.stopped, Status.paused]
value: Status.none, index: 0
value: Status.running, index: 1
value: Status.stopped, index: 2
value: Status.paused, index: 3
running: Status.running, 1
running index: Status.running
Dart Programming - 函数
函数是可读,可维护和可重用代码的构建块。 函数是一组用于执行特定任务的语句。 函数将程序组织成逻辑代码块。 一旦定义,就可以调用函数来访问代码。 这使得代码可以重用。 此外,函数可以轻松读取和维护程序的代码。
函数声明告诉编译器函数的名称,返回类型和参数。 函数定义提供函数的实际主体。
Sr.No | 功能和描述 |
---|---|
1 | 定义一个函数 函数定义指定特定任务的执行方式和方式。 |
2 | 调用函数 必须调用函数才能执行它。 |
3 | 返回功能 函数也可以将值与控制一起返回给调用者。 |
4 | 参数化功能 参数是一种将值传递给函数的机制。 |
可选参数
当函数执行时不需要强制传递参数时,可以使用可选参数。 通过在其名称后附加问号,可以将参数标记为可选。 可选参数应设置为函数中的最后一个参数。
我们在Dart中有三种可选参数 -
Sr.No | 参数和描述 |
---|---|
1 | 可选的位置参数 要指定可选的位置参数,请使用square []括号。 |
2 | 可选的命名参数 与位置参数不同,必须在传递值时指定参数的名称。 Curly brace {}可用于指定可选的命名参数。 |
3 | 带有默认值的可选参数 默认情况下,还可以为函数参数指定值。 但是,这些参数也可以显式传递值。 |
Dart递归函数 (Recursive Dart Functions)
递归是一种通过对函数自身重复调用直到它到达结果来迭代操作的技术。 当您需要使用循环内的不同参数重复调用相同的函数时,最好应用递归。
例子 (Example)
void main() {
print(factorial(6));
}
factorial(number) {
if (number <= 0) {
// termination case
return 1;
} else {
return (number * factorial(number - 1));
// function invokes itself
}
}
它应该产生以下output -
720
Lambda 函数
Lambda函数是表示函数的简明机制。 这些函数也称为箭头函数。
语法 (Syntax)
[return_type]function_name(parameters)=>expression;
例子 (Example)
void main() {
printMsg();
print(test());
}
printMsg()=>
print("hello");
int test()=>123;
// returning function
它应该产生以下output -
hello 123
Dart Programming - Interfaces
interface定义任何实体必须遵守的语法。 接口定义了一组对象可用的方法。 Dart没有声明接口的语法。 类声明本身就是Dart中的接口。
Classes应该使用implements关键字来使用接口。 实现类必须提供已实现接口的所有功能的具体实现。 换句话说,类必须重新定义它希望实现的接口中的每个函数。
语法:实现接口
class identifier implements interface_name
例子 (Example)
在以下程序中,我们声明了一个类Printer 。 ConsolePrinter类实现Printer类的隐式接口声明。 main函数使用new关键字创建ConsolePrinter类的对象。 该对象用于调用ConsolePrinter类中定义的函数print_data 。
void main() {
ConsolePrinter cp= new ConsolePrinter();
cp.print_data();
}
class Printer {
void print_data() {
print("__________Printing Data__________");
}
}
class ConsolePrinter implements Printer {
void print_data() {
print("__________Printing to Console__________");
}
}
它应该产生以下output -
__________Printing to Console__________
实现多个接口
一个类可以实现多个接口。 接口用逗号分隔。 下面给出了相同的syntax -
class identifier implements interface-1,interface_2,interface_4…….
以下example显示如何在Dart中实现多个接口 -
void main() {
Calculator c = new Calculator();
print("The gross total : ${c.ret_tot()}");
print("Discount :${c.ret_dis()}");
}
class Calculate_Total {
int ret_tot() {}
}
class Calculate_Discount {
int ret_dis() {}
}
class Calculator implements Calculate_Total,Calculate_Discount {
int ret_tot() {
return 1000;
}
int ret_dis() {
return 50;
}
}
它应该产生以下output -
The gross total: 1000
Discount:50
Dart Programming - Classes
Dart是一种面向对象的语言。 它支持面向对象的编程功能,如类,接口等.OOP方面的class是创建对象的蓝图。 class封装了对象的数据。 Dart为这个名为class概念提供了内置支持。
宣布一个class
使用class关键字在Dart中声明一个class 。 类定义以关键字class开头,后跟class name ; 并且由一对花括号包围的类体。 下面给出了相同的语法 -
语法 (Syntax)
class class_name {
<fields>
<getters/setters>
<constructors>
<functions>
}
class关键字后跟类名。 在命名类时必须考虑标识符的规则。
类定义可包括以下内容 -
Fields - 字段是类中声明的任何变量。 字段表示与对象有关的数据。
Setters and Getters - 允许程序初始化和检索类字段的值。 默认的getter/setter与每个类相关联。 但是,可以通过显式定义setter/getter来覆盖默认值。
Constructors - 负责为类的对象分配内存。
Functions - 函数表示对象可以采取的操作。 它们有时也被称为方法。
这些组件放在一起称为该类的data members 。
示例:声明一个类
class Car {
// field
String engine = "E1001";
// function
void disp() {
print(engine);
}
}
该示例声明了一个类Car 。 该类有一个名为engine的字段。 disp()是一个打印字段engine值的简单函数。
创建类的实例
要创建类的实例,请使用new关键字,后跟类名。 下面给出了相同的语法 -
语法 (Syntax)
var object_name = new class_name([ arguments ])
new关键字负责实例化。
表达式的右侧调用构造函数。 如果参数化,构造函数应该传递值。
示例:实例化一个类
var obj = new Car("Engine 1")
访问属性和函数 (Accessing Attributes and Functions)
可以通过对象访问类的属性和函数。 使用 '。' 用于访问类的数据成员的点表示法(称为period )。
//accessing an attribute
obj.field_name
//accessing a function
obj.function_name()
例子 (Example)
请看下面的示例,了解如何在Dart中访问属性和函数 -
void main() {
Car c= new Car();
c.disp();
}
class Car {
// field
String engine = "E1001";
// function
void disp() {
print(engine);
}
}
上述代码的output如下 -
E1001
Dart_programming构造师
构造函数是类的特殊函数,负责初始化类的变量。 Dart定义了一个与该类名称相同的构造函数。 构造函数是一个函数,因此可以参数化。 但是,与函数不同,构造函数不能具有返回类型。 如果未声明构造函数,则会为您提供默认的no-argument constructor 。
语法 (Syntax)
Class_name(parameter_list) {
//constructor body
}
例子 (Example)
以下示例显示如何在Dart中使用构造函数 -
void main() {
Car c = new Car('E1001');
}
class Car {
Car(String engine) {
print(engine);
}
}
它应该产生以下output -
E1001
命名的构造函数
Dart提供了named constructors以使类定义multiple constructors 。 命名构造函数的语法如下所示 -
语法:定义构造函数
Class_name.constructor_name(param_list)
例子 (Example)
以下示例显示如何在Dart中使用命名构造函数 -
void main() {
Car c1 = new Car.namedConst('E1001');
Car c2 = new Car();
}
class Car {
Car() {
print("Non-parameterized constructor invoked");
}
Car.namedConst(String engine) {
print("The engine is : ${engine}");
}
}
它应该产生以下output -
The engine is : E1001
Non-parameterized constructor invoked
这个关键字
this关键字引用类的当前实例。 这里,参数名称和类字段的名称是相同的。 因此,为了避免歧义,类的字段以this关键字为前缀。 以下示例解释相同 -
例子 (Example)
以下示例说明如何在Dart中使用this关键字 -
void main() {
Car c1 = new Car('E1001');
}
class Car {
String engine;
Car(String engine) {
this.engine = engine;
print("The engine is : ${engine}");
}
}
它应该产生以下output -
The engine is : E1001
Dart_programming类─吸气员和二传手
Getters和Setters ,也称为accessors mutators和更改mutators ,允许程序分别初始化和检索类字段的值。 使用get关键字定义getter或访问器。 Setter或mutator是使用set关键字定义的。
默认的getter/setter与每个类相关联。 但是,可以通过显式定义setter/getter来覆盖默认值。 getter没有参数并返回一个值,setter有一个参数并且不返回值。
语法:定义一个getter
Return_type get identifier
{
}
语法:定义一个setter
set identifier
{
}
例子 (Example)
以下示例显示如何在Dart类中使用getters和setters -
class Student {
String name;
int age;
String get stud_name {
return name;
}
void set stud_name(String name) {
this.name = name;
}
void set stud_age(int age) {
if(age<= 0) {
print("Age should be greater than 5");
} else {
this.age = age;
}
}
int get stud_age {
return age;
}
}
void main() {
Student s1 = new Student();
s1.stud_name = 'MARK';
s1.stud_age = 0;
print(s1.stud_name);
print(s1.stud_age);
}
该程序代码应产生以下output -
Age should be greater than 5
MARK
Null
类继承
Dart支持继承的概念,这是程序从现有类创建新类的能力。 扩展为创建较新类的类称为父类/超类。 新创建的类称为子/子类。
一个类使用'extends'关键字从另一个类继承。 Child classes inherit all properties and methods except constructors from the parent class 。
语法 (Syntax)
class child_class_name extends parent_class_name
Note - Dart不支持多重继承。
示例:类继承
在以下示例中,我们声明了一个类Shape 。 该类由Circle类扩展。 由于类之间存在继承关系,因此子类(即Car类)获得对其父类数据成员的隐式访问。
void main() {
var obj = new Circle();
obj.cal_area();
}
class Shape {
void cal_area() {
print("calling calc area defined in the Shape class");
}
}
class Circle extends Shape {}
它应该产生以下output -
calling calc area defined in the Shape class
继承的类型
继承可以是以下三种类型 -
Single - 每个类最多可以从一个父类扩展。
Multiple - 一个类可以从多个类继承。 Dart不支持多重继承。
Multi-level - 类可以从另一个子类继承。
例子 (Example)
以下示例显示了多级继承的工作原理 -
void main() {
var obj = new Leaf();
obj.str = "hello";
print(obj.str);
}
class Root {
String str;
}
class Child extends Root {}
class Leaf extends Child {}
//indirectly inherits from Root by virtue of inheritance
Leaf类通过多级继承从Root类和Child类派生属性。 其output如下 -
hello
Dart - 类继承和方法重写
方法重写是子类在其父类中重新定义方法的机制。 以下示例说明了相同的情况 -
例子 (Example)
void main() {
Child c = new Child();
c.m1(12);
}
class Parent {
void m1(int a){ print("value of a ${a}");}
}
class Child extends Parent {
@override
void m1(int b) {
print("value of b ${b}");
}
}
它应该产生以下output -
value of b 12
重写方法时,函数参数的数量和类型必须匹配。 如果参数数量或其数据类型不匹配,Dart编译器会抛出错误。 下图说明了相同的 -
import 'dart:io';
void main() {
Child c = new Child();
c.m1(12);
}
class Parent {
void m1(int a){ print("value of a ${a}");}
}
class Child extends Parent {
@override
void m1(String b) {
print("value of b ${b}");
}
}
它应该产生以下output -
value of b 12
静态关键字
static关键字可以应用于类的数据成员,即fields和methods 。 静态变量保留其值,直到程序完成执行。 静态成员由类名引用。
例子 (Example)
class StaticMem {
static int num;
static disp() {
print("The value of num is ${StaticMem.num}") ;
}
}
void main() {
StaticMem.num = 12;
// initialize the static variable }
StaticMem.disp();
// invoke the static method
}
它应该产生以下output -
The value of num is 12
超级关键字
super关键字用于指代类的直接父级。 关键字可用于引用variable, property,或method的超类版本。 以下示例说明了相同的情况 -
例子 (Example)
void main() {
Child c = new Child();
c.m1(12);
}
class Parent {
String msg = "message variable from the parent class";
void m1(int a){ print("value of a ${a}");}
}
class Child extends Parent {
@override
void m1(int b) {
print("value of b ${b}");
super.m1(13);
print("${super.msg}") ;
}
}
它应该产生以下output -
value of b 12
value of a 13
message variable from the parent class
Dart Programming - Object
面向对象编程将对象定义为“具有已定义边界的任何实体。”对象具有以下内容 -
State - 描述对象。 类的字段表示对象的状态。
Behavior - 描述对象可以执行的操作。
Identity - 区分对象与一组类似其他对象的唯一值。 两个或多个对象可以共享状态和行为,但不能共享身份。
句点运算符(.)与对象一起使用以访问类的数据成员。
例子 (Example)
Dart以对象的形式表示数据。 Dart中的每个类都扩展了Object类。 下面给出了一个创建和使用对象的简单示例。
class Student {
void test_method() {
print("This is a test method");
}
void test_method1() {
print("This is a test method1");
}
}
void main() {
Student s1 = new Student();
s1.test_method();
s1.test_method1();
}
它应该产生以下output -
This is a test method
This is a test method1
The Cascade operator (..)
上面的示例调用了类中的方法。 但是,每次调用函数时,都需要引用该对象。 在存在一系列调用的情况下, cascade operator可用作速记。
级联(..)运算符可用于通过对象发出一系列调用。 上述示例可以按以下方式重写。
class Student {
void test_method() {
print("This is a test method");
}
void test_method1() {
print("This is a test method1");
}
}
void main() {
new Student()
..test_method()
..test_method1();
}
它应该产生以下output -
This is a test method
This is a test method1
The toString() method
此函数返回对象的字符串表示形式。 请查看以下示例以了解如何使用toString方法。
void main() {
int n = 12;
print(n.toString());
}
它应该产生以下output -
12
Dart Programming - Collection
与其他编程语言不同,Dart不支持数组。 Dart集合可用于复制数组结构等数据结构。 dart:核心库和其他类在Dart脚本中启用Collection支持。
Dart_programming收藏基本上可归类为 -
Sr.No | Dart_programming收集和描述 |
---|---|
1 | List List只是一组有序的对象。 dart:core库提供了List类,可以创建和操作列表。
|
2 | Set Set表示对象的集合,其中每个对象只能出现一次。 dart:core库提供了Set类来实现相同的功能。 |
3 | Maps Map对象是一个简单的键/值对。 地图中的键和值可以是任何类型。 地图是动态集合。 换句话说,Maps可以在运行时增长和缩小。 dart:core库中的Map类提供了对它的支持。 |
4 | Queue 队列是一个可以在两端操作的集合。 当您想要构建先进先出集合时,队列非常有用。 简而言之,队列从一端插入数据并从另一端删除。 按插入顺序删除/读取值。 |
迭代集合
来自dart:core库的Iterator类可以轻松进行集合遍历。 每个集合都有一个iterator属性。 此属性返回指向集合中对象的迭代器。
例子 (Example)
以下示例说明如何使用迭代器对象遍历集合。
import 'dart:collection';
void main() {
Queue numQ = new Queue();
numQ.addAll([100,200,300]);
Iterator i= numQ.iterator;
while(i.moveNext()) {
print(i.current);
}
}
moveNext()函数返回一个布尔值,指示是否存在后续条目。 迭代器对象的current属性返回迭代器当前指向的对象的值。
该程序应产生以下output -
100
200
300
Dart Programming - Generics
Dart是一种optionally typed language 。 Dart中的集合默认是异构的。 换句话说,单个Dart集合可以托管各种类型的值。 但是,可以使Dart集合保持同质值。 泛型的概念可用于实现相同的目的。
泛型的使用强制限制集合可以包含的值的数据类型。 这种集合被称为类型安全集合。 类型安全是一种编程功能,可确保内存块只能包含特定数据类型的数据。
所有Dart集合都通过泛型支持类型安全实现。 包含数据类型的一对尖括号用于声明类型安全的集合。 声明类型安全集合的语法如下所示。
语法 (Syntax)
Collection_name <data_type> identifier= new Collection_name<data_type>
下面给出了List,Map,Set和Queue的类型安全实现。 上述集合类型的所有实现也支持此功能。
示例:通用列表
void main() {
List <String> logTypes = new List <String>();
logTypes.add("WARNING");
logTypes.add("ERROR");
logTypes.add("INFO");
// iterating across list
for (String type in logTypes) {
print(type);
}
}
它应该产生以下output -
WARNING
ERROR
INFO
尝试插入指定类型以外的值将导致编译错误。 以下示例说明了这一点。
例子 (Example)
void main() {
List <String> logTypes = new List <String>();
logTypes.add(1);
logTypes.add("ERROR");
logTypes.add("INFO");
//iterating across list
for (String type in logTypes) {
print(type);
}
}
它应该产生以下output -
1
ERROR
INFO
示例:通用集
void main() {
Set <int>numberSet = new Set<int>();
numberSet.add(100);
numberSet.add(20);
numberSet.add(5);
numberSet.add(60);
numberSet.add(70);
// numberSet.add("Tom");
compilation error;
print("Default implementation :${numberSet.runtimeType}");
for(var no in numberSet) {
print(no);
}
}
它应该产生以下output -
Default implementation :_CompactLinkedHashSet<int>
100
20
5
60
70
示例:通用队列
import 'dart:collection';
void main() {
Queue<int> queue = new Queue<int>();
print("Default implementation ${queue.runtimeType}");
queue.addLast(10);
queue.addLast(20);
queue.addLast(30);
queue.addLast(40);
queue.removeFirst();
for(int no in queue){
print(no);
}
}
它应该产生以下output -
Default implementation ListQueue<int>
20
30
40
通用地图
类型安全的映射声明指定数据类型 -
- The key
- The value
语法 (Syntax)
Map <Key_type, value_type>
例子 (Example)
void main() {
Map <String,String>m={'name':'Tom','Id':'E1001'};
print('Map :${m}');
}
它应该产生以下output -
Map :{name: Tom, Id: E1001}
Dart Programming - Packages
包是一种封装一组编程单元的机制。 应用程序有时可能需要集成某些第三方库或插件。 每种语言都有一种机制来管理外部软件包,如Maven或Gradle for Java,Nuget for .NET,npm for Node.js等.Dart的软件包管理器是pub 。
Pub有助于在存储库中安装包。 托管软件包的存储库可以在https://pub.dartlang.org/.找到https://pub.dartlang.org/.
package metadata在文件pubsec.yaml定义。 YAML是Yet Another Markup Language的首字母缩写。 pub工具可用于下载应用程序所需的所有各种库。
每个Dart应用程序都有一个pubspec.yaml文件,其中包含对其他库的应用程序依赖性以及应用程序的元数据,如应用程序名称,作者,版本和描述。
pubspec.yaml文件的内容应如下所示:
name: 'vector_victor'
version: 0.0.1
description: An absolute bare-bones web app.
...
dependencies: browser: '>=0.10.0 <0.11.0'
重要的pub commands如下 -
Sr.No | 命令和描述 |
---|---|
1 | 'pub get' 帮助您获取应用程序所依赖的所有包。 |
2 | 'pub upgrade' 将所有依赖项升级到较新版本。 |
3 | 'pub build' 这用于构建您的Web应用程序,它将创建一个构建文件夹,其中包含所有相关脚本。 |
4 | 'pub help' 这将为您提供所有不同pub命令的帮助。 |
如果您使用的是像WebStorm这样的IDE,那么您可以右键单击pubspec.yaml直接获取所有命令 -
安装包
考虑应用程序需要解析xml的示例。 Dart XML是一个轻量级的库,它是开源的,可以稳定地解析,遍历,查询和构建XML文档。
完成上述任务的步骤如下 -
Step 1 - 将以下内容添加到pubsec.yaml文件中。
name: TestApp
version: 0.0.1
description: A simple console application.
#dependencies:
# foo_bar: '>=1.0.0 <2.0.0'
dependencies: https://mail.google.com/mail/u/0/images/cleardot.gif
xml:
右键单击pubsec.yaml并获取依赖项。 这将在内部触发pub get command ,如下所示。
可以在packages文件夹下验证下载的包及其相关包。
由于现在安装完成,我们需要在项目中引用dart xml 。 语法如下 -
import 'package:xml/xml.dart' as xml;
读取XML字符串
要读取XML字符串并验证输入,Dart XML使用parse()方法。 语法如下 -
xml.parse(String input):
示例:解析XML字符串输入
以下示例显示如何解析XML字符串输入 -
import 'package:xml/xml.dart' as xml;
void main(){
print("xml");
var bookshelfXml = '''<?xml version = "1.0"?>
<bookshelf>
<book>
<title lang = "english">Growing a Language</title>
<price>29.99</price>
</book>
<book>
<title lang = "english">Learning XML</title>
<price>39.95</price>
</book>
<price>132.00</price>
</bookshelf>''';
var document = xml.parse(bookshelfXml);
print(document.toString());
}
它应该产生以下output -
xml
<?xml version = "1.0"?><bookshelf>
<book>
<title lang = "english">Growing a Language</title>
<price>29.99</price>
</book>
<book>
<title lang = "english">Learning XML</title>
<price>39.95</price>
</book>
<price>132.00</price>
</bookshelf>
Dart Programming - Exceptions
异常(或异常事件)是在执行程序期间出现的问题。 发生异常时,程序的正常流程中断,程序/应用程序异常终止。
内置Dart_programming例外包括 -
Sr.No | 例外与描述 |
---|---|
1 | DeferredLoadException 延迟库无法加载时抛出。 |
2 | FormatException 当字符串或某些其他数据不具有预期格式且无法解析或处理时抛出异常。 |
3 | IntegerDivisionByZeroException 当数字除以零时抛出。 |
4 | IOException 所有与Inupt-Output相关的异常的基类。 |
5 | IsolateSpawnException 无法创建隔离时抛出。 |
6 | Timeout 在等待异步结果时发生计划超时时抛出。 |
Dart中的每个异常都是预定义类Exception的子类型。 必须处理异常以防止应用程序突然终止。
try/on/catch块
try块嵌入可能导致异常的代码。 需要指定异常类型时使用on块。 当处理程序需要异常对象时,将使用catch块。
try块必须紧跟一个on/catch块或一个finally块(或两者之一)。 当try块中发生异常时,控件将转移到catch 。
处理异常的syntax如下所示 -
try {
// code that might throw an exception
}
on Exception1 {
// code for handling exception
}
catch Exception2 {
// code for handling exception
}
以下是要记住的一些要点 -
代码段可以有多个on/catch块来处理多个异常。
on块和catch块是相互包含的,即try块可以与on块和catch块相关联。
以下代码说明了Dart中的异常处理 -
示例:使用ON块
以下程序分别用变量x和y表示的两个数字。 代码抛出异常,因为它尝试除零。 on block包含处理此异常的代码。
main() {
int x = 12;
int y = 0;
int res;
try {
res = x ~/ y;
}
on IntegerDivisionByZeroException {
print('Cannot divide by zero');
}
}
它应该产生以下output -
Cannot divide by zero
示例:使用catch块
在以下示例中,我们使用了与上面相同的代码。 唯一的区别是catch block (而不是ON块)包含处理异常的代码。 catch的参数包含在运行时抛出的异常对象。
main() {
int x = 12;
int y = 0;
int res;
try {
res = x ~/ y;
}
catch(e) {
print(e);
}
}
它应该产生以下output -
IntegerDivisionByZeroException
示例:on ... catch
以下示例显示如何使用on...catch块。
main() {
int x = 12;
int y = 0;
int res;
try {
res = x ~/ y;
}
on IntegerDivisionByZeroException catch(e) {
print(e);
}
}
它应该产生以下output -
IntegerDivisionByZeroException
最后一块
finally块包括应该执行的代码,而不管异常的发生。 在try/on/catch之后无条件执行可选的finally块。
使用finally块的语法如下 -
try {
// code that might throw an exception
}
on Exception1 {
// exception handling code
}
catch Exception2 {
// exception handling
}
finally {
// code that should always execute; irrespective of the exception
}
以下示例说明了finally块的使用。
main() {
int x = 12;
int y = 0;
int res;
try {
res = x ~/ y;
}
on IntegerDivisionByZeroException {
print('Cannot divide by zero');
}
finally {
print('Finally block executed');
}
}
它应该产生以下output -
Cannot divide by zero
Finally block executed
抛出异常
throw关键字用于显式引发异常。 应该处理引发的异常,以防止程序突然退出。
显式引发异常的syntax是 -
throw new Exception_name()
例子 (Example)
以下示例显示如何使用throw关键字抛出异常 -
main() {
try {
test_age(-2);
}
catch(e) {
print('Age cannot be negative');
}
}
void test_age(int age) {
if(age<0) {
throw new FormatException();
}
}
它应该产生以下output -
Age cannot be negative
自定义例外
如上所述,Dart中的每个异常类型都是内置类Exception的子类型。 Dart可以通过扩展现有异常来创建自定义异常。 定义自定义异常的语法如下所示 -
语法:定义异常
class Custom_exception_Name implements Exception {
// can contain constructors, variables and methods
}
应明确引发自定义异常,并在代码中处理相同的异常。
例子 (Example)
以下示例显示如何定义和处理自定义异常。
class AmtException implements Exception {
String errMsg() => 'Amount should be greater than zero';
}
void main() {
try {
withdraw_amt(-1);
}
catch(e) {
print(e.errMsg());
}
finally {
print('Ending requested operation.....');
}
}
void withdraw_amt(int amt) {
if (amt <= 0) {
throw new AmtException();
}
}
在上面的代码中,我们定义了一个自定义异常AmtException 。 如果传递的金额不在例外范围内,则代码会引发异常。 main函数将函数调用包含在try...catch块中。
代码应该产生以下output -
Amount should be greater than zero
Ending requested operation....
Dart Programming - Debugging
不时,开发人员在编码时会犯错误。 程序中的错误被称为错误。 查找和修复错误的过程称为调试,是开发过程的正常部分。 本节介绍可以帮助您完成调试任务的工具和技术。
WebStorm编辑器启用断点和逐步调试。 程序将在断点附加点处中断。 此功能类似于您对Java或C#应用程序开发的期望。 您可以从WebStorm编辑器中观察变量,浏览堆栈,跳过步骤并进入方法和函数调用。
添加断点
请考虑以下代码段。 (TestString.dart)
void main() {
int a = 10, b = 20, c = 5;
c = c * c * c;
print("$a + $b = ${a+b}");
print("$a%$b = ${a%b}"); // Add a break point here
print("$a*$b = ${a*b}");
print("$a/$b = ${a/b}");
print(c);
}
要add a breakpoint ,请单击左边距。 在下面给出的图中,第7行有一个断点。
Run the program in debug mode 。 在项目浏览器中右键单击我们的案例TestString.dart中的dart程序。
程序在调试模式下运行后,您将进入Debugger窗口,如以下屏幕截图所示。 变量选项卡显示当前上下文中的变量值。 您可以为特定变量添加观察者,并使用监视窗口监听值更改。
调试菜单上的Step Into (F7)箭头图标有助于一次执行一个代码语句。 如果main方法调用子例程,那么这也将进入子例程代码。
Step over (F8):它类似于Step Into 。 当前语句包含对子例程的调用时,会出现使用上的差异。 如果main方法调用子例程,则跳过将不会深入到子例程。 它会跳过子程序。
Step Out (Shift + F8):执行当前执行点所在的函数的剩余行。 显示的下一个语句是子程序调用后的语句。
在调试模式下运行后,程序提供以下output -
10 + 20 = 30
10 % 20 = 10
10 * 20 = 200
10/20 = 0.5
125
Dart Programming - Typedef
typedef或函数类型别名有助于定义指向内存中可执行代码的指针。 简单地说, typedef可以用作引用函数的指针。
下面给出了在Dart程序中实现typedefs的步骤。
Step 1: Defining a typedef
typedef可用于指定我们希望特定函数匹配的函数签名。 函数签名由函数的参数(包括其类型)定义。 返回类型不是函数签名的一部分。 其语法如下。
typedef function_name(parameters)
Step 2: Assigning a Function to a typedef Variable
typedef的变量可以指向与typedef具有相同签名的任何函数。 您可以使用以下签名将函数分配给typedef变量。
type_def var_name = function_name
Step 3: Invoking a Function
typedef变量可用于调用函数。 以下是调用函数的方法 -
var_name(parameters)
例子 (Example)
现在让我们举一个例子来了解Dart中关于typedef更多信息。
首先,让我们定义一个typedef 。 这里我们定义一个函数签名。 该函数将采用integer类型的两个输入参数。 返回类型不是函数签名的一部分。
typedef ManyOperation(int firstNo , int secondNo); //function signature
接下来,让我们定义函数。 使用与ManyOperation typedef相同的函数签名定义一些函数。
Add(int firstNo,int second){
print("Add result is ${firstNo+second}");
}
Subtract(int firstNo,int second){
print("Subtract result is ${firstNo-second}");
}
Divide(int firstNo,int second){
print("Add result is ${firstNo/second}");
}
最后,我们将通过typedef调用该函数。 声明ManyOperations类型的变量。 将函数名称分配给声明的变量。
ManyOperation oper ;
//can point to any method of same signature
oper = Add;
oper(10,20);
oper = Subtract;
oper(30,20);
oper = Divide;
oper(50,5);
oper变量可以指向任何采用两个整数参数的方法。 Add函数的引用被赋给变量。 Typedef可以在运行时切换函数引用
现在让我们将所有部分放在一起,看看完整的程序。
typedef ManyOperation(int firstNo , int secondNo);
//function signature
Add(int firstNo,int second){
print("Add result is ${firstNo+second}");
}
Subtract(int firstNo,int second){
print("Subtract result is ${firstNo-second}");
}
Divide(int firstNo,int second){
print("Divide result is ${firstNo/second}");
}
Calculator(int a, int b, ManyOperation oper){
print("Inside calculator");
oper(a,b);
}
void main(){
ManyOperation oper = Add;
oper(10,20);
oper = Subtract;
oper(30,20);
oper = Divide;
oper(50,5);
}
该程序应产生以下output -
Add result is 30
Subtract result is 10
Divide result is 10.0
Note - 如果typedef变量尝试指向具有不同函数签名的函数,则上述代码将导致错误。
例子 (Example)
Typedefs也可以作为参数传递给函数。 考虑以下示例 -
typedef ManyOperation(int firstNo , int secondNo); //function signature
Add(int firstNo,int second){
print("Add result is ${firstNo+second}");
}
Subtract(int firstNo,int second){
print("Subtract result is ${firstNo-second}");
}
Divide(int firstNo,int second){
print("Divide result is ${firstNo/second}");
}
Calculator(int a,int b ,ManyOperation oper){
print("Inside calculator");
oper(a,b);
}
main(){
Calculator(5,5,Add);
Calculator(5,5,Subtract);
Calculator(5,5,Divide);
}
它将产生以下output -
Inside calculator
Add result is 10
Inside calculator
Subtract result is 0
Inside calculator
Divide result is 1.0
Dart Programming - Libraries
编程语言中的库表示例程集合(编程指令集)。 Dart有一组内置库,可用于存储经常使用的例程。 Dart库由一组类,常量,函数,typedef,属性和异常组成。
导入库
导入使库中的组件可用于调用者代码。 import关键字用于实现相同的目标。 dart文件可以有多个import语句。
内置Dart库URI使用dart:scheme来引用库。 其他库可以使用文件系统路径或package:scheme来指定其URI。 包管理器(如pub工具)提供的库使用package: scheme 。
下面给出了在Dart中导入库的语法 -
import 'URI'
请考虑以下代码段 -
import 'dart:io'
import 'package:lib1/libfile.dart'
如果只想使用库的一部分,则可以有选择地导入库。 下面给出了相同的语法 -
import 'package: lib1/lib1.dart' show foo, bar;
// Import only foo and bar.
import 'package: mylib/mylib.dart' hide foo;
// Import all names except foo
下面给出了一些常用的库 -
Sr.No | 图书馆与描述 |
---|---|
1 | dart:io 服务器应用程序的文件,套接字,HTTP和其他I/O支持。 此库在基于浏览器的应用程序中不起作用。 默认情况下导入此库。 |
2 | dart:core 每个Dart程序的内置类型,集合和其他核心功能。 该库是自动导入的。 |
3 | dart: math 数学常数和函数,加上随机数生成器。 |
4 | dart: convert 用于在不同数据表示之间进行转换的编码器和解码器,包括JSON和UTF-8。 |
5 | dart: typed_data 有效处理固定大小数据的列表(例如,无符号8字节整数)。 |
示例:导入和使用库
以下示例导入内置库dart: math 。 该片段从math库中调用sqrt()函数。 此函数返回传递给它的数字的平方根。
import 'dart:math';
void main() {
print("Square root of 36 is: ${sqrt(36)}");
}
Output
Square root of 36 is: 6.0
封装在库中
Dart脚本可以使用下划线(_)为标识符添加前缀,以将其组件标记为私有。 简而言之,Dart库可以通过外部脚本限制对其内容的访问。 这被称为encapsulation 。 下面给出了相同的语法 -
语法 (Syntax)
_identifier
例子 (Example)
首先,使用私有函数定义库。
library loggerlib;
void _log(msg) {
print("Log method called in loggerlib msg:$msg");
}
接下来,导入库
import 'test.dart' as web;
void main() {
web._log("hello from webloggerlib");
}
上面的代码将导致错误。
Unhandled exception:
No top-level method 'web._log' declared.
NoSuchMethodError: method not found: 'web._log'
Receiver: top-level
Arguments: [...]
#0 NoSuchMethodError._throwNew (dart:core-patch/errors_patch.dart:184)
#1 main (file:///C:/Users/Administrator/WebstormProjects/untitled/Assertion.dart:6:3)
#2 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:261)
#3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)
创建自定义库
Dart还允许您将自己的代码用作库。 创建自定义库涉及以下步骤 -
Step 1: Declaring a Library
要显式声明库,请使用library statement 。 声明库的语法如下 -
library library_name
// library contents go here
Step 2: Associating a Library
您可以通过两种方式关联库 -
- 在同一目录中
import 'library_name'
- 来自不同的目录
import 'dir/library_name'
示例:自定义库
首先,让我们定义一个自定义库, calculator.dart 。
library calculator_lib;
import 'dart:math';
//import statement after the libaray statement
int add(int firstNumber,int secondNumber){
print("inside add method of Calculator Library ") ;
return firstNumber+secondNumber;
}
int modulus(int firstNumber,int secondNumber){
print("inside modulus method of Calculator Library ") ;
return firstNumber%secondNumber;
}
int random(int no){
return new Random().nextInt(no);
}
接下来,我们将导入库 -
import 'calculator.dart';
void main() {
var num1 = 10;
var num2 = 20;
var sum = add(num1,num2);
var mod = modulus(num1,num2);
var r = random(10);
print("$num1 + $num2 = $sum");
print("$num1 % $num2= $mod");
print("random no $r");
}
该程序应产生以下output -
inside add method of Calculator Library
inside modulus method of Calculator Library
10 + 20 = 30
10 % 20= 10
random no 0
库前缀
如果导入两个具有冲突标识符的库,则可以为一个或两个库指定前缀。 使用'as'关键字指定前缀。 下面给出了相同的语法 -
语法 (Syntax)
import 'library_uri' as prefix
例子 (Example)
首先,让我们定义一个库: loggerlib.dart 。
library loggerlib;
void log(msg){
print("Log method called in loggerlib msg:$msg");
}
接下来,我们将定义另一个库: webloggerlib.dart 。
library webloggerlib;
void log(msg){
print("Log method called in webloggerlib msg:$msg");
}
最后,我们将导入带有前缀的库。
import 'loggerlib.dart';
import 'webloggerlib.dart' as web;
// prefix avoids function name clashes
void main(){
log("hello from loggerlib");
web.log("hello from webloggerlib");
}
它将产生以下output -
Log method called in loggerlib msg:hello from loggerlib
Log method called in webloggerlib msg:hello from webloggerlib
Dart Programming - Async
asynchronous operation在线程中执行,与main应用程序线程分开。 当应用程序调用方法异步执行操作时,应用程序可以在异步方法执行其任务时继续执行。
例子 (Example)
让我们举个例子来理解这个概念。 这里,程序使用IO library接受用户输入。
import 'dart:io';
void main() {
print("Enter your name :");
// prompt for user input
String name = stdin.readLineSync();
// this is a synchronous method that reads user input
print("Hello Mr. ${name}");
print("End of main");
}
readLineSync()是一种同步方法。 这意味着将阻止执行readLineSync()函数调用之后的所有指令,直到readLineSync()方法完成执行。
stdin.readLineSync等待输入。 它停在轨道上,并且在收到用户的输入之前不再执行任何操作。
以上示例将产生以下output -
Enter your name :
Tom
// reads user input
Hello Mr. Tom
End of main
在计算中,我们说当某个事件在继续之前等待事件发生时,它是synchronous 。 这种方法的一个缺点是,如果代码的一部分花费太长时间来执行,则后续的块(尽管不相关)将被阻止执行。 考虑一个必须响应多个资源请求的Web服务器。
同步执行模型将阻止每个其他用户的请求,直到它完成处理当前请求。 在这种情况下,与Web服务器的情况一样,每个请求必须独立于其他请求。 这意味着,Web服务器在响应其他用户的请求之前不应等待当前请求完成执行。
简而言之,在完成先前用户的请求之前,它应该接受来自新用户的请求。 这被称为异步。 异步编程基本上意味着没有等待或非阻塞编程模型。 dart:async包有助于在Dart脚本中实现异步编程块。
例子 (Example)
以下示例更好地说明了异步块的功能。
Step 1 - 创建如下所示的contact.txt文件and并将其保存在当前项目的数据文件夹中。
1, Tom
2, John
3, Tim
4, Jane
Step 2 - 编写一个程序,它将读取文件而不会阻止应用程序的其他部分。
import "dart:async";
import "dart:io";
void main(){
File file = new File( Directory.current.path+"\\data\\contact.txt");
Future<String> f = file.readAsString();
// returns a futrue, this is Async method
f.then((data)=>print(data));
// once file is read , call back method is invoked
print("End of main");
// this get printed first, showing fileReading is non blocking or async
}
该计划的output如下 -
End of main
1, Tom
2, John
3, Tim
4, Jan
当脚本继续读取文件时,首先执行“main of main”。 Future类是dart:async一部分,用于在异步任务完成后获取计算结果。 然后,此Future值用于在计算完成后执行某些操作。
一旦读取操作完成,执行控制就在"then()"内传送。 这是因为读取操作可能需要更多时间,因此不希望阻止程序的其他部分。
Dart_programming未来
Dart社区将Future定义为“在Future某个时间获取价值的手段”。 简单地说, Future objects是一种表示由表达式返回的值的机制,该表达式的执行将在稍后的时间点完成。 当调用异步方法时,Dart的几个内置类返回Future 。
Dart是一种单线程编程语言。 如果任何代码阻塞执行线程(例如,通过等待耗时的操作或阻塞I/O),程序将有效冻结。
异步操作可让您的程序运行而不会被阻止。 Dart使用Future objects来表示异步操作。
Dart Programming - Concurrency
Concurrency是同时执行多个指令序列。 它涉及同时执行多个任务。
Dart使用Isolates作为并行工作的工具。 dart:isolate包是Dart的解决方案,用于获取单线程Dart代码并允许应用程序更多地使用可用的硬件。
Isolates ,顾名思义,是运行代码的独立单元。 在它们之间发送数据的唯一方法是传递消息,就像在客户端和服务器之间传递消息的方式一样。 isolate可帮助程序充分利用多核微处理器的优势。
例子 (Example)
让我们举个例子来更好地理解这个概念。
import 'dart:isolate';
void foo(var message){
print('execution from foo ... the message is :${message}');
}
void main(){
Isolate.spawn(foo,'Hello!!');
Isolate.spawn(foo,'Greetings!!');
Isolate.spawn(foo,'Welcome!!');
print('execution from main1');
print('execution from main2');
print('execution from main3');
}
这里, Isolate类的spawn方法有助于与我们的其余代码并行运行函数foo 。 spawn函数有两个参数 -
- 产生的功能,和
- 将传递给衍生函数的对象。
如果没有对象传递给生成的函数,则可以传递NULL值。
这两个函数(foo and main)可能不一定每次都以相同的顺序运行。 无法保证foo何时执行以及何时执行main() 。 每次运行时输出都不同。
输出1
execution from main1
execution from main2
execution from main3
execution from foo ... the message is :Hello!!
输出2
execution from main1
execution from main2
execution from main3
execution from foo ... the message is :Welcome!!
execution from foo ... the message is :Hello!!
execution from foo ... the message is :Greetings!!
从输出中,我们可以得出结论,Dart代码可以从运行代码中生成新的isolate ,就像Java或C#代码可以启动新线程一样。
Isolates与线程的不同之处在于isolate有自己的内存。 无法在isolates之间共享变量 - isolates区之间进行通信的唯一方法是通过消息传递。
Note - 对于不同的硬件和操作系统配置,上述输出将有所不同。
隔离v/s Future
异步执行复杂的计算工作对于确保应用程序的响应性非常重要。 Dart Future是一种在完成后检索异步任务的值的机制,而Dart Isolates是一种抽象并行性并在实际的高级基础上实现它的工具。
Dart Programming - Unit Testing
单元测试涉及测试应用程序的每个单元。 它可以帮助开发人员在不运行整个复杂应用程序的情况下测试小功能。
名为“test”的Dart external library提供了编写和运行单元测试的标准方法。
Dart_programming单元测试涉及以下步骤 -
Step 1: Installing the "test" package
要在当前项目中安装第三方软件包,您需要pubspec.yaml文件。 要安装test packages ,首先在pubspec.yaml文件中进行以下输入 -
dependencies:
test:
输入后,右键单击pubspec.yaml文件并获取依赖项。 它将安装"test"包。 下面给出了WebStorm编辑器中相同的屏幕截图。
包也可以command line安装。 在终端中键入以下内容 -
pub get
Step 2: Importing the "test" package
import "package:test/test.dart";
Step 3 Writing Tests
使用顶级函数test()指定test() ,而使用expect()函数进行test assertions 。 要使用这些方法,应将它们安装为pub依赖项。
语法 (Syntax)
test("Description of the test ", () {
expect(actualValue , matchingValue)
});
group()函数可用于对测试进行分组。 每个组的描述都添加到其测试描述的开头。
语法 (Syntax)
group("some_Group_Name", () {
test("test_name_1", () {
expect(actual, equals(exptected));
});
test("test_name_2", () {
expect(actual, equals(expected));
});
})
例1:通过测试
以下示例定义方法Add() 。 此方法采用两个整数值并返回表示sum的整数。 要测试这个add()方法 -
Step 1 - 导入test包,如下所示。
Step 2 - 使用test()函数定义测试。 这里, test()函数使用expect()函数来强制执行断言。
import 'package:test/test.dart';
// Import the test package
int Add(int x,int y)
// Function to be tested {
return x+y;
}
void main() {
// Define the test
test("test to check add method",(){
// Arrange
var expected = 30;
// Act
var actual = Add(10,20);
// Asset
expect(actual,expected);
});
}
它应该产生以下output -
00:00 +0: test to check add method
00:00 +1: All tests passed!
示例2:失败测试
下面定义的subtract()方法存在逻辑错误。 以下test验证相同。
import 'package:test/test.dart';
int Add(int x,int y){
return x+y;
}
int Sub(int x,int y){
return x-y-1;
}
void main(){
test('test to check sub',(){
var expected = 10;
// Arrange
var actual = Sub(30,20);
// Act
expect(actual,expected);
// Assert
});
test("test to check add method",(){
var expected = 30;
// Arrange
var actual = Add(10,20);
// Act
expect(actual,expected);
// Asset
});
}
Output - 函数add()的测试用例通过,但subtract()的测试失败,如下所示。
00:00 +0: test to check sub
00:00 +0 -1: test to check sub
Expected: <10>
Actual: <9>
package:test expect
bin\Test123.dart 18:5 main.<fn>
00:00 +0 -1: test to check add method
00:00 +1 -1: Some tests failed.
Unhandled exception:
Dummy exception to set exit code.
#0 _rootHandleUncaughtError.<anonymous closure> (dart:async/zone.dart:938)
#1 _microtaskLoop (dart:async/schedule_microtask.dart:41)
#2 _startMicrotaskLoop (dart:async/schedule_microtask.dart:50)
#3 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:394)
#4 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:414)
#5 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)
分组测试用例
您可以对test cases进行分组,以便为测试代码添加更多含义。 如果您有许多test cases这有助于编写更清晰的代码。
在给定的代码中,我们正在为split()函数和trim函数编写测试用例。 因此,我们在逻辑上将这些测试用例分组并称之为String 。
例子 (Example)
import "package:test/test.dart";
void main() {
group("String", () {
test("test on split() method of string class", () {
var string = "foo,bar,baz";
expect(string.split(","), equals(["foo", "bar", "baz"]));
});
test("test on trim() method of string class", () {
var string = " foo ";
expect(string.trim(), equals("foo"));
});
});
}
Output - 输出将附加每个测试用例的组名称,如下所示 -
00:00 +0: String test on split() method of string class
00:00 +1: String test on trim() method of string class
00:00 +2: All tests passed
Dart Programming - HTML DOM
每个网页都位于浏览器窗口内,可以将其视为对象。
Document object表示在该窗口中显示的HTML文档。 Document对象具有各种属性,这些属性引用允许访问和修改文档内容的其他对象。
访问和修改文档内容的方式称为Document Object Model或DOM 。 对象按层次结构组织。 此分层结构适用于Web文档中对象的组织。
Window - 层次结构的顶部。 它是对象层次结构的最外层元素。
Document - 加载到窗口中的每个HTML文档都成为文档对象。 该文档包含页面的内容。
Elements - 表示网页上的内容。 示例包括文本框,页面标题等。
Nodes - 通常是元素,但它们也可以是属性,文本,注释和其他DOM类型。
这是一些重要DOM对象的简单层次结构 -
Dart提供了dart:html库来操作DOM中的对象和元素。 基于控制台的应用程序无法使用dart:html库。 要在Web应用程序中使用HTML库,请导入dart:html -
import 'dart:html';
接下来,我们将在下一节讨论一些DOM Operations 。
寻找DOM元素
dart:html库提供querySelector函数来搜索DOM中的元素。
Element querySelector(String selectors);
querySelector()函数返回与指定的选择器组匹配的第一个元素。 "selectors应该是使用CSS选择器语法的字符串,如下所示
var element1 = document.querySelector('.className');
var element2 = document.querySelector('#id');
示例:操作DOM
按照下面给出的步骤,在Webstorm IDE中 -
Step 1 - 文件NewProject→在该位置,提供项目名称DemoWebApp 。
Step 1 - 在“生成示例内容”部分中,选择SimpleWebApplication 。
它将创建一个示例项目DemoWebApp 。 有一个pubspec.yaml文件,其中包含需要下载的依赖项。
name: 'DemoWebApp'
version: 0.0.1
description: An absolute bare-bones web app.
#author: Your Name <email@example.com>
#homepage: https://www.example.com
environment:
sdk: '>=1.0.0 <2.0.0'
dependencies:
browser: '>=0.10.0 <0.11.0' dart_to_js_script_rewriter: '^1.0.1'
transformers:
- dart_to_js_script_rewriter
如果您已连接到Web,那么这些将自动下载,否则您可以右键单击pubspec.yaml并获取依赖项。
在Web文件夹中,您将找到三个文件: Index.html, main.dart和style.css
Index.html
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<meta http-equiv = "X-UA-Compatible" content = "IE = edge">
<meta name = "viewport" content = "width = device-width, initial-scale = 1.0">
<meta name = "scaffolded-by" content = "https://github.com/google/stagehand">
<title>DemoWebApp</title>
<link rel = "stylesheet" href = "styles.css">
<script defer src = "main.dart" type = "application/dart"></script>
<script defer src = "packages/browser/dart.js"></script>
</head>
<body>
<h1>
<div id = "output"></div>
</h1>
</body>
</html>
Main.dart
import 'dart:html';
void main() {
querySelector('#output').text = 'Your Dart web dom app is running!!!.';
}
运行index.html文件; 您将在屏幕上看到以下输出。
事件处理
dart:html库为DOM Elements提供onClick事件。 语法显示了元素如何处理点击事件流。
querySelector('#Id').onClick.listen(eventHanlderFunction);
querySelector()函数返回给定DOM中的元素, onClick.listen()将采用eventHandler方法,该方法将在引发click事件时调用。 eventHandler的语法如下 -
void eventHanlderFunction (MouseEvent event){ }
现在让我们举个例子来理解Dart中事件处理的概念。
TestEvent.html
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<meta http-equiv = "X-UA-Compatible" content = "IE = edge">
<meta name = "viewport" content = "width = device-width, initial-scale = 1.0">
<meta name = "scaffolded-by" content ="https://github.com/google/stagehand">
<title>DemoWebApp</title>
<link rel = "stylesheet" href = "styles.css">
<script defer src = "TestEvent.dart" type="application/dart"></script>
<script defer src = "packages/browser/dart.js"></script>
</head>
<body>
<div id = "output"></div>
<h1>
<div>
Enter you name : <input type = "text" id = "txtName">
<input type = "button" id = "btnWish" value="Wish">
</div>
</h1>
<h2 id = "display"></h2>
</body>
</html>
TestEvent.dart
import 'dart:html';
void main() {
querySelector('#btnWish').onClick.listen(wishHandler);
}
void wishHandler(MouseEvent event){
String name = (querySelector('#txtName') as InputElement).value;
querySelector('#display').text = 'Hello Mr.'+ name;
}