目录
Dart介绍
一些Dart的重要概念
Dart语法学习
变量
内建类型
Number
String
Boolean
List
Set
Map
Symbol
函数
参数类型(可选参数,必选参数)
函数作为另一个函数的参数
匿名函数
运算符
关系运算符
类型判定运算符
赋值运算符
逻辑运算符
按位和移位运算符
条件表达式
级联运算符 (..)
回调函数
Dart是谷歌开发的计算机编程语言,它被用于web、服务器、移动应用和物联网等领域的开发。Dart是面向对象的、类定义的、单继承的语言。
变量和数据类型:Dart是一种强类型语言,变量需要显式声明类型或使用类型推断。Dart支持多种数据类型,包括数字、字符串、布尔值、列表、映射等。
函数:Dart中的函数是一等公民,可以作为参数传递给其他函数,也可以作为返回值。函数可以有命名参数、可选参数和默认参数。
类和对象:Dart是一种面向对象的语言,支持类和对象的概念。类是对象的蓝图,用于定义对象的属性和方法。对象是类的实例,可以通过构造函数创建。
继承和多态:Dart支持类的继承,一个类可以继承另一个类的属性和方法。通过继承,可以实现代码的重用和扩展。Dart也支持多态,允许使用父类的引用来引用子类的对象。
接口:Dart中的接口是一种约定,用于定义类应该实现的方法。Dart中的类可以实现一个或多个接口,以实现多态和代码复用。
异步编程:Dart内置了异步编程的支持,使用async和await关键字可以方便地处理异步操作,例如网络请求、文件读写等。Dart中的异步操作可以是Future、Stream或者是自定义的异步函数。
异常处理:Dart中的异常处理使用try-catch语句来捕获和处理异常。可以捕获特定类型的异常,并根据需要执行相应的处理逻辑。
泛型:Dart支持泛型,可以在类、函数和接口中使用泛型来增加代码的灵活性和重用性。泛型允许在编译时指定类型参数。
Mixins:Dart中的Mixin是一种代码复用机制,允许将一组方法和属性注入到类中,以增强类的功能,而无需继承。
引入和导入:Dart中可以使用import关键字引入其他Dart文件或库,使用export关键字将当前文件的内容导出给其他文件使用。
任何保存在变量中的都是一个 对象 , 并且所有的对象都是对应一个 类 的实例。 无论是数字,函数和 null
都是对象。所有对象继承自 Object类。
尽管 Dart 是强类型的,但是 Dart 可以推断类型,所以类型注释是可选的。 如果要明确说明不需要任何类型, [需要使用特殊类型 dynamic
] 。
Dart 支持泛型,如 List
(整数列表)或 List
(任何类型的对象列表)。
Dart 支持顶级函数(这些函数不会封装在一个类或者对象当中,所有的应用程序都至少有一个顶级函数,例如 main()
), 同样函数绑定在类或对象上(分别是 静态函数 和 实例函数 )。 以及支持函数内创建函数 ( 嵌套 或 局部函数 ) 。
类似地, Dart 支持顶级 变量 , 同样变量绑定在类或对象上(静态变量和实例变量)。 实例变量有时称为字段或属性。
与 Java 不同,Dart 没有关键字 “public” , “protected” 和 “private” 。 如果标识符以下划线(_)开头,则它相对于库是私有的。
标识符 以字母或下划线(_)开头,后跟任意字母和数字组合。
//这里会类型推断出是String类型,(使用var定义的变量值可以被修改)
var name = "Bob";
//也可显示指定变量类型
String name = "Bob";
//使用过程中从来不会被修改的变量, 可以使用 final 或 const定义。final修饰的值只能设置一次,可以理解为final修饰的变量是不可改变的,而const修饰的表示一个常量。
final name = 'Bob';
const bar = 1000000; // 压力单位 (dynes/cm2)
//final,const区别
区别一:final 要求变量只能初始化一次,并不要求赋的值一定是编译时常量,可以是常量也可以不是。而 const 要求在声明时初始化,并且赋值必需为编译时常量。区别二:final 是惰性初始化,即在运行时第一次使用前才初始化。而 const 是在编译时就确定值了。
Dart 语言支持以下内建类型:
Number
String
Boolean
List (也被称为 Array)
Map
Set
Rune (用于在字符串中表示 Unicode 字符)
Symbol
Dart 语言的 Number 有两种类型:int double
字符串,数字互转
// String -> int
var one = int.parse('1');
assert(one == 1);
// String -> double
var onePointOne = double.parse('1.1');
assert(onePointOne == 1.1);
// int -> String
String oneAsString = 1.toString();
assert(oneAsString == '1');
// double -> String
String piAsString = 3.14159.toStringAsFixed(2);
assert(piAsString == '3.14');
var s1 = 'hello';
var s2 = 'world';
//字符串可以通过 ${expression} 的方式内嵌表达式
print("${s1}");
//可以使用 + 运算符来把多个字符串连接为一个
print('${s1 + s2}');
print(s1 + s2);
Dart 的类型安全意味着不能使用 if (nonbooleanValue) 或者 assert (nonbooleanValue)。 而是应该像下面这样,明确的进行值检查:
// 检查空字符串。
var fullName = '';
assert(fullName.isEmpty);
// 检查 0 值。
var hitPoints = 0;
assert(hitPoints <= 0);
// 检查 null 值。
var unicorn;
assert(unicorn == null);
// 检查 NaN 。
var iMeantToDoThis = 0 / 0;
assert(iMeantToDoThis.isNaN);
//定义一个List
var list = [1, 2, 3];
//获取list长度
print(list.length);
print(list.isEmpty);
print(list.isNotEmpty);
//倒序
print(list.reversed.toList());
//修改
print(list.fillRange(1,2,'hah'));//打印[1,hah,3]。
//获取指定下表的元素
list[1] = 1;
(是没有顺序且不能重复的集合,所以不能通过索引去获取值。)
// Set names = {}; // 这样也是可以的。
// var names = {}; // 这样会创建一个 Map ,而不是 Set 。
var names = {};
//添加元素
names.add('fluorine');
//获取Set长度
print(names.length);
var gifts = {
// Key: Value
'first': 'partridge',
'second': 'turtledoves',
'fifth': 'golden rings'
};
//或
var gifts = Map();
gifts['first'] = 'partridge';
gifts['second'] = 'turtledoves';
gifts['fifth'] = 'golden rings';
一个 Symbol 对象表示 Dart 程序中声明的运算符或者标识符。 你也许永远都不需要使用 Symbol ,但要按名称引用标识符的 API 时, Symbol 就非常有用了。 因为代码压缩后会改变标识符的名称,但不会改变标识符的符号。 通过字面量 Symbol ,也就是标识符前面添加一个 # 号,来获取标识符的 Symbol 。
#radix
#bar
//示例
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
//当函数中只有一句表达式,可以使用简写语法(也叫箭头语法)
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
//可选参数可以是命名参数或者位置参数,但一个参数只能选择其中一种方式修饰。
//命名参数
enableFlags(bold: true, hidden: false);
//位置可选参数,将参数放到 [] 中来标记参数是可选的
String say(String from, String msg, [String device]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
return result;
}
void printElement(int element) {
print(element);
}
var list = [1, 2, 3];
// 将 printElement 函数作为参数传递。
list.forEach(printElement);
多数函数是有名字的, 比如 main() 和 printElement()。 也可以创建没有名字的函数,这种函数被称为 匿名函数。
var list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
print('${list.indexOf(item)}: $item');
});
算术运算符
//稍有不同的
assert(5 / 2 == 2.5); // 结果是双浮点型
assert(5 ~/ 2 == 2); // 结果是整型
assert(5 % 2 == 1); // 余数
== != > < >= <=
as, is, 和 is! 运算符用于在运行时处理类型检查。
is运算符用于判断一个变量是不是某个类型的数据
is!则是判断变量不是某个类型的数据
使用 as 运算符将对象强制转换为特定类型。 通常,可以认为是 is 类型判定后,被判定对象调用函数的一种缩写形式。
if (emp is Person) {
// Type check
emp.firstName = 'Bob';
}
//使用 as 运算符进行缩写:
(emp as Person).firstName = 'Bob';
使用 = 为变量赋值。 使用 ??= 运算符时,只有当被赋值的变量为 null 时才会赋值给它。
// 将值赋值给变量a
a = value;
// 如果b为空时,将变量赋值给b,否则,b的值保持不变。
b ??= value;
与或非
在 Dart 中,可以单独操作数字的某一位。 通常情况下整数类型使用按位和移位运算符来操作。
& | ^ ~expr << >>
final value = 0x22;
final bitmask = 0x0f;
assert((value & bitmask) == 0x02); // AND
assert((value & ~bitmask) == 0x20); // AND NOT
assert((value | bitmask) == 0x2f); // OR
assert((value ^ bitmask) == 0x2d); // XOR
assert((value << 4) == 0x220); // Shift left
assert((value >> 4) == 0x02); // Shift right
condition ? expr1 : expr2
如果条件为 true, 执行 expr1 (并返回它的值): 否则, 执行并返回 expr2 的值。
expr1 ?? expr2
如果 expr1 是 non-null, 返回 expr1 的值; 否则, 执行并返回 expr2 的值。
级联运算符 (..) 可以实现对同一个对像进行一系列的操作。 除了调用函数, 还可以访问同一对象上的字段属性。 这通常可以节省创建临时变量的步骤, 同时编写出更流畅的代码。
querySelector('#confirm') // 获取对象。
..text = 'Confirm' // 调用成员变量。
..classes.add('important')
..onClick.listen((e) => windnow.alert('Confirmed!'));
//等价于下面的代码
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
//级联运算符还可嵌套
final addressBook = (AddressBookBuilder()
..name = 'jenny'
..email = '[email protected]'
..phone = (PhoneNumberBuilder()
..number = '415-555-0100'
..label = 'home')
.build()).build();
在Flutter中,可以使用回调函数来处理事件的返回值或者异步操作的结果。下面是一个简单的示例,展示了如何在Flutter中使用回调函数
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Callback Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(
title: 'Callback Demo',
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
String _result = '';
void _showResult(String result) {
setState(() {
_result = result;
});
}
void _doSomething() {
// 模拟一个耗时操作
Future.delayed(Duration(seconds: 2), () {
String result = '操作完成';
_showResult(result);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: _doSomething,
child: Text('执行操作'),
),
SizedBox(height: 20),
Text(
_result,
style: TextStyle(fontSize: 20),
),
],
),
),
);
}
}
在这个示例中,我们创建了一个简单的Flutter应用,包含一个按钮和一个文本框。当用户点击按钮时,会执行一个耗时操作,并将操作结果通过回调函数传递给主页面。然后,我们使用setState
方法来更新界面上的文本框,显示操作结果。
在_MyHomePageState
类中,我们定义了一个_showResult
方法,用于更新操作结果。然后,在_doSomething
方法中,我们使用Future.delayed
来模拟一个耗时操作,并在操作完成后调用_showResult
方法来更新界面。