Flutter-从入门到项目
04:Dart语法快速掌握(上)
使用Flutter内置美丽的 Material Design
和 Cupertino
(iOS风格)widget
、丰富的motion API
、平滑而自然的滑动效果和平台感知,为您的用户带来全新体验。
但是这些丝滑的界面也是一行一行的 Dart代码
构建而成,所以了解和掌握 Dart语法
非常重要
我知道可能这一篇文章你不会详细读 ===> 换成是我,我也不会,谁会那么枯燥的啃语法,尤其这么一个快节奏的时代.但是 Dart语法
太重要了???,希望你这一遍粗略的读一下,然后点赞收藏???,等待你针对某一个地方语法不明确的时候.可以根据标签目录,快速查阅???(就当字典工具一样)
那么接下来我们开始从变量和操作符到类和库给大家一点一点介绍一下! 详细的内容大家可以参考Dart官方文档:
ps: 这里给大家推荐一下 Open DartPad 就类似 Swift的 Playground
是不是感觉也是非常便利,其实我们简单的语法测试,完全可以用这个,简单明了!!!?
01
① Dart 的重要概念
TITTLES
- ?每个变量都是一个对象,每个对象是一个类的实例。甚至数字,函数,和null都是对象。所有对象都继承自 Object类
- ?指定静态类型(如 num前面的例子中)讲清意图,用
tools
开启静态检查,但它是可选的。(可能注意到当你调试代码,没有指定类型的变量会得到一个特殊的类型:dynamic
) - ?
Dart
解析所有的代码运行之前。可以对Dart提供提示,例如,通过使用类型或编译时间常数来捕获错误或帮助代码运行更快。 - ?
Dart
支持顶级函数(如main()
)也支持类或者对象(静态和实例方法分别支持)里的函数。还可以在函数里创建函数(嵌套或局部功能)。 - ?类似的,
Dart
支持顶级变量,以及依赖于类或对象(静态变量和实例变量)变量。实例变量有时被称为域或属性。 - ?与
Java
不同,Dart
不具备关键字public,protected和private
。如果一个标识符以下划线(_)
开始,那么它和它的库都是私有的。有关详细信息,请参阅 Libraries and visibility。 - ?标识符可以字母或
(_)
开始,或者是字符加数字的组合开头。 - ?有时,判断是一个表达式还是一个语句会很重要,所以我们要准确了解这两个单词。
- ?
Dart tools
可报告两类问题:警告(warning ⚠️)和错误(error ❎)。警告只是迹象表明,代码可能无法正常工作,但他们不会阻止程序的执行。错误可以是编译时或运行时,编译时的错误阻止代码执行;当代码执行时一个运行时的错误会导致一个 异常(exception)被抛出。 - ?Dart有两种运行模式:生产 (
production
) 和检查 (checked
) 。我们建议在检查模式开发和调试,并将其部署到生产模式。 - ?
Production mode
是Dart程序一个速度优化的默认运行模式。Production mode
忽略 断言语句(assert statements) 和静态类型。 - ?
Checked mode
是开发人员友好的方式,可以帮助你在运行时捕捉一些类型的错误。例如,如果分配一个非数字来声明为一个num
变量,然后在检查模式会抛出异常。 - ?编程语言并不是孤立存在的,Dart也是这样,他由语言规范、虚拟机、类库和工具等组成:
- SDK:SDK 包含
Dart VM、dart2js、Pub
、库和工具。 - Dartium:内嵌
Dart VM
的Chromium
,可以在浏览器中直接执行dart 代码
。 - Dart2js:将
Dart
代码编译为JavaScript
的工具。 - Dart Editor:基于
Eclipse
的全功能 IDE,并包含以上所有工具。支持代码补全、代码导航、快速修正、重构、调试等功能。
- SDK:SDK 包含
02
② 关键字
TITTLES
关键字 | 关键字 | 关键字 | 关键字 |
---|---|---|---|
abstract 2 | else | import 2 | super |
as 2 | enum | in | switch |
assert | export 2 | interface 2 | sync 1 |
async 1 | extends | is | this |
await 3 | extension 2 | library 2 | throw |
break | external 2 | mixin 2 | true |
case | factory 2 | new | try |
catch | false | null | typedef 2 |
class | final | on 1 | var |
const | finally | operator 2 | void |
continue | for | part 2 | while |
covariant 2 | Function 2 | rethrow | with |
default | get 2 | return | yield 3 |
deferred 2 | hide 1 | set 2 | static 2 |
do | if | show 1 | implements 2 |
dynamic 2 |
- 带有上标1的单词是上下文关键词,它们只有在特定的地方才有意义。它们到处都是有效的标识符。
- 带有上标2的单词是内置标识符。为了简化将
JavaScript
代码移植到Dart
的任务,这些关键字在大多数地方都是有效的标识符,但它们不能用作类或类型名,也不能用作导入前缀。 - 带有上标3的单词是与Dart 1.0发布后添加的异步支持相关的较新的、有限的保留单词。不能在任何标记为
async
、async*
或sync*
的函数体中使用await
或yield
作为标识符。 - 表中的所有其他字都是保留字,不能作为标识符。
- 标识符是给予程序中元素的名称,如变量,函数等。标识符的规则是
标识符可以包括字符和数字。 但是,标识符不能以数字开头。
- 除下划线(_)或美元符号($)外,标识符不能包含特殊符号。
- 标识符不能是关键字。
- 它们必须是独一无二的
- 标识符区分大小写。
- 标识符不能包含空格。
有效标识符 | 无效标识符 |
---|---|
firstName | Var |
first_name | first name |
num1 | first-name |
$result | 1number |
03
③ Dart面向对象思想
TITTLES
Dart是一种面向对象的语言。 面向对象是一种遵循真实世界建模的软件开发范例。 Object Orientation
将程序视为通过称为方法的机制相互通信的对象集合。
A: 对象
对象 – 对象是任何实体的实时表示。 根据 Grady Brooch
,每个对象必须具有三个功能
- 状态 – 由对象的属性描述。
- 行为 – 描述对象的行为方式。
- 标识 – 将对象与一组类似此类对象区分开的唯一值。
类
类 – OOP
方面的类是创建对象的蓝图。 类封装了对象的数据。
方法
方法 – 方法促进对象之间的通信。
代码语言:javascript复制// main入口函数
void main() {
// 面向对象
KCClass cls = new KCClass();
cls.sayHello();
}
class KCClass{
void sayHello(){
print('Hello Dart');
}
}
复制代码
04
④ 变量 & 常量
TITTLES
1: 变量
下面我们开始初始化一个变量 : name
很简单,跟我们开发iOS Android 没有太多的去呗
// 变量声明初始化
void varibleFunc(){
var name = 'cooci';
dynamic nickName = 'KC';
Object person = '酷C';
// 显示声明将被推断类型, 可以使用String显示声明字符串类型
String company = 'LG' ;
print('i am: $name,$nickName,$person ,$company');
}
复制代码
变量存储引用。名为 name
的变量包含对值为“ cooci” 的字符串对象的引用。
name
变量的类型被推断为 String
,声明没有静态类型的变量被隐式声明为动态。 也可以使用 dynamic关键字
代替 var关键字
声明变量,请参考design guidelines指定 Object
或者 dynamic
。
显示声明将被推断类型, 可以使用String
显示声明字符串类型
2: 默认值
未初始化的变量具有 null
的初始值。即使数字类型变量最初为 null ,因为数字是对象。
// 默认值
int age;
assert(age == null);
print(age); //打印结果为null,证明数字类型初始化值是null
复制代码
3: Final and const
如果您从未打算更改变量,可以使用 final
或 const
来代替 var
或添加到类型之外。final变量
只能设置一次; const变量
是编译时常量。(Const变量
隐式为final
。)最终的顶级变量或类变量在第一次使用时进行初始化。
// Final and const
// Final and const
final student = 'JZ';
final String studentName = '家振';
print('student = ,${[student,studentName]}');
// 被 final 或 const 修饰的变量无法再去修改其值。
// student = 'chen'; // a final variable, can only be set once
const teacher = 'Kody';
// 这样写,编译器提示:Constant variables can't be assigned a value
// teacher = 'Cat';
// flnal 或者 const 不能和 var 同时使用
// Members can't be declared to be both 'const' and 'var'
// const var String teacherName = 'CC';
// final var String teacherName = 'hank';
// 常量如果是类级别的,请使用 static const
static const String lector = 'sky';
复制代码
其实这里跟我们平时的开发认知是相同的! 所以大家稍微可以带过.
05
⑤ 内置类型
TITTLES
Dart
语言对以下类型有特殊的支持:
- ?numbers
- ?strings
- ?booleans
- ?lists (also known as arrays)
- ?sets
- ?maps
- ?runes (for expressing Unicode characters in a string)
- ?symbols
可以使用字面量 初始化这些特殊类型中的任何一个对象。例如,'this is a string'
是一个字符串字面量,而 true
是一个布尔字面量。
因为 Dart
中的每个变量都指向一个对象(类的实例),所以通常可以使用构造函数来初始化变量。一些内置类型有自己的构造函数。例如,您可以使用 Map()
构造函数来创建映射。
A: num类型
Dart num
有两种: int
double
// 关于num 类型测试
void numFunc() {
int a = 1;
print(a);
double b = 1.12;
print(b);
// String -> int
int one = int.parse('1');
// 输出3
print(one 2);
// String -> double
var onePointOne = double.parse('1.1');
// 输出3.1
print(onePointOne 2);
// int -> String
String oneAsString = 1.toString();
// The argument type 'int' can't be assigned to the parameter type 'String'
//print(oneAsString 2);
// 输出 1 2
print('$oneAsString 2');
// 输出 1 2
print('$oneAsString 2');
// double -> String 注意括号中要有小数点位数,否则报错
String piAsString = 3.14159.toStringAsFixed(2);
// 截取两位小数, 输出3.14
print(piAsString);
String aString = 1.12618.toStringAsFixed(2);
// 检查是否四舍五入,输出1.13,发现会做四舍五入
print(aString);
}
复制代码
其中大体都是相似,iOS开发注意咯 : 类型直接相互转换的代码!
B: Strings 类型
Dart字符串
是由UTF-16编码单元组成的序列。可以使用单引号
或双引号
创建字符串:- 可以使用相邻的字符串字直接连接在一起 或者
操作符
来连接字符串: - 另一种创建多行字符串的方法是:
使用带有单引号
或双引号的三引号:
- 单引号或者双引号里面嵌套使用引号。
- 用
{}
来计算字符串中变量的值,需要注意的是如果是表达式需要${表达式}
// 关于string 类型测试
void stringFunc() {
// `Dart字符串` 是由UTF-16编码单元组成的序列。可以使用`单引号`或`双引号`创建字符串:
var s1 = '和谐学习,不急不躁';
var s2 = "等风来不如追风去,总有那么一个人在风景正好的季节来到你的身边,并且懂得你全部的好!!!";
var s3 = '我是Cooci';
var s4 = 'cooci';
assert( '$s3' == '我是' 'Cooci');
assert( '${s4.toUpperCase()}' == 'COOCI');
// 可以使用相邻的字符串字直接连接在一起 或者 ` 操作符` 来连接字符串:
var s5 = 'LG_''Cooci_'"和谐学习不急不躁";
assert(s5 ==
'LG_Cooci_和谐学习不急不躁');
var s6 = 'LG_' 'Cooci';
assert(s6 == 'LG_Cooci');
// 另一种创建多行字符串的方法是:`使用带有单引号` 或 `双引号的三引号:`
var s7 = '''
单引号创建多行字符串
注意要各行哦''';
var s8 = """双引号创建多行字符串
注意要各行哦""";
print(s7);
print(s8);
// 单引号或者双引号里面嵌套使用引号。
// 用 {} 来计算字符串中变量的值,需要注意的是如果是表达式需要${表达式}
// 单引号嵌套双引号
String s9 = '$s1 a "LG" ${s3}';
// 输出 和谐学习,不急不躁 a "LG" 我是Cooci
print(s9);
// 双引号嵌套单引号
String s10 = "${s4.toUpperCase()} abc 'LG' $s4.toUpperCase()";
// 输出 COOCI abc 'aaa' cooci.toUpperCase(),
// 可以看出 '$s4.toUpperCase()' 没有加'{}',导致输出结果是'cooci.toUpperCase()'
print(s10);
}
复制代码
C: Bool 类型
为了表示布尔值,Dart有一个名为 bool
的类型。只有两个对象具有 bool类型
: 布尔字面值 true
和 false
,它们都是编译时常量。因为和我们一般了解一致 我们就不展开篇幅
D: Lists 类型
数组集合类型是比较广泛适用的! Dart
里面的 Lists
相对 OC
来说比较简单. 重点也在 增删改查
,详情大家查阅?代码
// Lists 类型测试
void listsFunc(){
// Dart推断list的类型为list <int>
// 如果尝试将非整数对象添加到此列表中,分析器或运行时将引发错误
var list = [1, 2, 3];
// 要创建一个编译时常量的列表,在列表字面量之前添加const:
var constantList = const [1, 2, 3];
// constantList[1] = 1; // 报错
// spread operator (...) 的用法
var list1 = [1, 2, 3];
var list2 = [0, ...list1];
print(list2); // [0, 1, 2, 3]
// 注意插入空的情况 那么就需要 `(...?)`
var list3 ;
var list4 = [0, ...?list3];
print(list4); // [0]
// list 增删改查
var list5 = [1, 2, 3];
list5.add(4); print(list5); // [1, 2, 3, 4]
// 删除元素
list5.remove(4); print(list5); // [1, 2, 3]
list5.removeAt(0); print(list5); // [2, 3]
// 修改元素
list5[1] = 100; print(list5); // [2, 100]
// 查询
print(list5.indexOf(2)); // 0
print(list5.elementAt(1)); // 100
print(list5.contains(666)); // false
}
复制代码
这里做一个表 方便大家快速查阅学习,代码你可以敲一下,如果没有时间也可以不用敲了(比较简单 ?)
操作 | 代码 | 含义 | 输出 |
---|---|---|---|
初始化 | var list5 = [1, 2, 3] | 初始化了一个数组: list5 里面有三个 int 类型的元素: 1, 2, 3 | [1, 2, 3] |
新增 | list5.add(4) | 在末尾新增元素: 4 | [1, 2, 3, 4] |
移除 | list5.remove(4) | 移除元素: 4 | [1, 2, 3] |
修改 | list5[1] = 100 | 把下标为 1 的元素修改成 100 | [1, 100, 3] |
查询 | list5.elementAt(2) | 查询在下标为: 2 的元素 | 100 |
判断 | list5.contains(666) | 判断是否存在 666 元素 | false |
E: Sets 类型
Sets
就是无序集合, 大体的用法也和其他语言相似
// Sets 类型测试
void setsFunc(){
var names = <String>{}; // 或者 Set<String> names = {};
// ⚠️ var names = {}; // 创建的是一个 map, 不是 set.
names.add('teachers');
print(names); // {teachers}
var persons = {'hank', 'cooci', 'kody', 'cc', 'cat'};
names.addAll(persons);
print('$names,${names.length}'); // {teachers, hank, cooci, kody, cc, cat}, 6
}
复制代码
F: Maps 类型
map
是一个关联键和值的对象 (也就是我们所说的字典)
map
中的键值对是唯一的map
里面的value
可以相同map
里面的value
可以为空字符串map
里面的value
可以为null
// Maps 类型测试
void mapsFunc(){
var person = {
// Key: Value
'age': 18,
'name': 'cooci',
'hobby': '女',
'height': 1.85
};
print(person); // {age: 18, name: cooci, hobby: 女, height: 1.85}
print('${person.keys},${person.values}'); // (age, name, hobby, height),(18, cooci, 女, 1.85)
// Map的赋值,中括号中是Key,这里可不是数组
person['age'] = '20';
//Map中的键值对是唯一的
//同Set不同,第二次输入的Key如果存在,Value会覆盖之前的数据
person['name'] = 'hank';
// map里面的value可以相同
person['hobby'] = 'cooci';
// map里面value可以为空字符串
person['hobby'] = '';
// map里面的value可以为null
person['height'] = null;
print(person); // {age: 20, name: hank, hobby: , height: null}
}
复制代码
06
⑥ 参考文献