本文更新于2024-12-22,使用Dart 2.18.2。
可以使用dart run FILENAME
运行程序文件。
关键字
- abstract
- as
- assert
- async
- await
- break
- case
- catch
- class
- const
- continue
- covariant
- default
- deferred
- do
- dynamic
- else
- enum
- export
- extends
- external
- factory
- false
- final
- finally
- for
- get
- hide
- if
- implements
- import
- in
- interface
- is
- library
- mixin
- new
- null
- on
- operator
- part
- rethrow
- return
- set
- show
- static
- super
- switch
- sync
- this
- throw
- true
- try
- typedef
- var
- void
- while
- with
- yield
常量
const声明的是编译时常量。
| cosnt s1 = ""; |
| const String s2 = ""; |
| |
| final s3 = ""; |
| final String s4 = ""; |
| |
| var list = const[1, 2, 3]; |
| const list = [1, 2, 3]; |
| |
| var dog = const Dog(); |
| const dog = Dog(); |
变量
| var a1; |
| var a2 = null; |
| dynamic a3; |
| dynamic a4 = ""; |
| |
| var s1 = ""; |
| String s2 = ""; |
基本数据类型
数值
- int: 64位。范围为[-2^63 ~ 263-1]。编译为JavaScript时使用JavaScript的范围[-253 ~ 2^53-1]。
- double:64位。范围约为[-1.7E308 ~ 1.7E308]。
字符串
使用UTF-16编码。
| var s1 = '\''; |
| var s2 = "\""; |
| |
| var s3 = '''1 |
| 2'''; |
| var s4 = """1 |
| 2"""; |
| |
| var s5 = "\u2665\u{1f47b}"; |
| |
| var a1 = '$s1 ${s2}'; |
| var a2 = "$s1 ${s2}"; |
| var a3 = s1 + " " + s2; |
| var a4 = s1 * 3; |
| var a5 = "${s1+s2}"; |
布尔
| var b1 = true; |
| bool b2 = false; |
列表
集合
映射
| var m1 = {}; |
| var m2 = { |
| "a": 1, |
| "b": "2" |
| }; |
运算符
运算符优先级
从高到低依次为:
描述 |
运算符 |
一元后缀 |
++,--,(),[],.,?. |
一元前缀 |
-,!,~,++,-- |
乘除 |
*,/,~/,% |
加减 |
+,- |
移位 |
<<,>>,>>> |
按位与 |
& |
按位异或 |
^ |
按位或 |
| |
关系和类型测试 |
>=,>,<=,<,as,is,is! |
相等判断 |
==,!= |
逻辑与 |
&& |
逻辑或 |
|| |
为空判断 |
?? |
条件 |
? : |
级联 |
.. |
赋值 |
=,+=,-=,*=,/=,~/=,%=,<<=,>>=,>>>=,&=,^=,|= |
算数运算符
运算符 |
用法 |
描述 |
+ |
1 + 2 |
相加 |
- |
1 - 2 |
相减 |
- |
-1 |
负数 |
* |
1 * 2 |
相乘 |
/ |
1 / 2 |
相除(返回浮点数) |
~/ |
1 ~/ 2 |
相除(返回整数) |
% |
1 % 2 |
取余 |
++ |
++n |
(前)自增 |
++ |
n++ |
(后)自增 |
-- |
--n |
(前)自减 |
-- |
n-- |
(后)自减 |
关系运算符
运算符 |
用法 |
描述 |
== |
1 == 2 |
相等 |
!= |
1 != 2 |
不等 |
> |
1 > 2 |
大于 |
>= |
1 >= 2 |
大于等于 |
< |
1 < 2 |
小于 |
<= |
1 <= 2 |
小于等于 |
类型判定运算符
运算符 |
用法 |
描述 |
as |
1 as int |
类型转换(结果为运算符后的类型) |
is |
1 is int |
是此类型(结果为bool类型) |
is! |
1 is! int |
非此类型(结果为bool类型) |
赋值运算符
运算符 |
用法 |
描述 |
= |
n = 2 |
赋值 |
+= |
n += 2 |
即 n = n + 2 |
-= |
n -= 2 |
即 n = n - 2 |
*= |
n *= 2 |
即 n = n * 2 |
/= |
n /= 2 |
即 n = n / 2 |
~/= |
n ~/= 2 |
即 n = n ~/ 2 |
%= |
n %= 2 |
即 n = n % 2 |
<<= |
n <<= 2 |
即 n = n << 2 |
>>= |
n >>= 2 |
即 n = n >> 2 |
>>>= |
n >>>= 2 |
即 n = n >>> 2 |
&= |
n &= 2 |
即 n = n & 2 |
|= |
n |= 2 |
即 n = n | 2 |
^= |
n ^= 2 |
即 n = n ^ 2 |
逻辑运算符
运算符 |
用法 |
描述 |
! |
!true |
非 |
|| |
true || false |
或 |
&& |
true && false |
与 |
位运算符
运算符 |
用法 |
描述 |
& |
1 & 2 |
按位与 |
| |
1 | 2 |
按位或 |
^ |
1 ^ 2 |
按位异或 |
~ |
~1 |
按位取反(结果为相反数减一) |
<< |
1 << 2 |
按位左移 |
>> |
1 >> 2 |
有符号按位右移(左侧填充符号位) |
>>> |
1 >>> 2 |
无符号按位右移(左侧填充0) |
条件运算符
运算符 |
用法 |
描述 |
? : |
v ? t : f |
条件判断(如v为true取值t,否则取值f) |
?? |
v ?? n |
非空判断(如v非null取值v,否则取值n) |
访问运算符
运算符 |
用法 |
描述 |
() |
f() |
函数调用 |
[] |
a[1] |
使用索引访问元素 |
. |
a.b |
访问对象成员 |
?. |
a?.b |
条件访问对象成员(如a非null取值b,否则取值null) |
.. |
v..f1()..f2() |
级联运算(等价于v.f1();v.f2(),严格意义上并不是一个运算符,只是一个特殊语法) |
流程控制
条件语句
if-else
| if (condition1) { |
| } else if (condition2) { |
| } else { |
| } |
switch-case
| switch (v) { |
| case 1: |
| case 2: |
| print(""); |
| break; |
| default: |
| } |
循环语句
for
| for (var i = 0; i < n; i++) { |
| } |
for-in
while
do-while
break语句
| switch (v) { |
| case 1: |
| case 2: |
| print(""); |
| break; |
| default: |
| } |
| |
| for (var i = 0; i < n; i++) { |
| break; |
| print(i); |
| } |
continue语句
| for (var i = 0; i < n; i++) { |
| if (i == 0) { |
| continue; |
| } |
| print(i); |
| } |
断言
断言只在开发(Checked)模式下有效,在生产(Production)模式下无效。
异常
| try { |
| throw new Exception(); |
| } on RangeError { |
| rethrow; |
| } catch (e) { |
| } finally { |
| } |
函数
| String join(String a, String b) { |
| return a + b; |
| } |
| |
| add(a, b) { |
| return a + b; |
| } |
| |
| run() { |
| } |
| var s = join("a", "b"); |
| var n = add(1, 2); |
| var a = run(); |
箭头函数
| String join(String a, String b) => a + b; |
可选位置参数
| String join(String a, String b, [String c = "", String d = ""]) { |
| return a + b + c + d; |
| } |
| var s = join("a", "b", "c"); |
可选命名参数
| String join(String a, String b, {String c: "", d: ""}) { |
| return a + b + c + d; |
| } |
| var s = join("a", "b", c: "c"); |
闭包
| Function hello(String name) { |
| var say = () { |
| print("Hello $name"); |
| }; |
| return say; |
| } |
| var say = hello("Tom"); |
| say(); |
主函数
| void main(List<String> args) { |
| } |
类
成员变量/实例变量
| class Person { |
| String name = ""; |
| int age = 0; |
| } |
getter和setter
会为每个成员变量自动生成getter方法,对于非final修饰的成员变量也会自动生成setter方法。
| class Person { |
| String name = ""; |
| |
| String get Name { |
| return name; |
| } |
| |
| set Name(String n) { |
| name = n; |
| } |
| } |
| var p = new Person(); |
| p.Name = "Tom"; |
| print(p.Name); |
静态变量/类变量
| class Person { |
| String name = ""; |
| int age = 0; |
| |
| static int total = 1000; |
| static Person me = new Person(); |
| } |
构造函数
构造函数的执行顺序为:实例变量赋值 -> 初始化参数列表 -> 父类构造函数 -> 本类构造函数。
默认无参构造函数
| class Person { |
| String name = ""; |
| int age = 0; |
| } |
| var p1 = new Person(); |
| var p2 = Person(); |
默认自动生成无参构造函数:
显式声明构造函数
| class Person { |
| String name = ""; |
| int age = 0; |
| |
| Person(String name, int age) { |
| this.name = name; |
| this.age = age; |
| } |
| } |
| var p = new Person("Tom", 10); |
命名构造函数
| class Person { |
| String name = ""; |
| int age = 0; |
| |
| Person.myself(age) { |
| name = "Tom"; |
| this.age = age; |
| } |
| } |
| var p = new Person.myself(10); |
构造函数简写
| class Person { |
| String name = ""; |
| int age = 0; |
| |
| Person(this.name, this.age); |
| |
| Person.create(this.name, {this.age: 0}); |
| } |
| |
| class Student extends Person { |
| String number = ""; |
| |
| Student(super.name, super.age); |
| } |
| var p1 = new Person("Tom", 10); |
| var p2 = new Person.create("Tom", age: 10); |
| |
| var s = new Student("Tom", 10); |
初始化列表
| class Person { |
| String name = ""; |
| int age = 0; |
| |
| Person.myself(int age): name = "Tom", this.age = age { |
| } |
| } |
| var p = new Person.myself(10); |
重定向构造函数
| class Person { |
| String name = ""; |
| int age = 0; |
| |
| Person(this.name, this.age); |
| |
| Person.myself(int age): this("Tom", age); |
| } |
| var p = new Person.myself(10); |
常量构造函数
| class Person { |
| final String name; |
| final int age; |
| |
| const Person(this.name, this.age); |
| } |
| var p1 = new Person("Tom", 10); |
| var p2 = const Person("Tom", 10); |
工厂方法的构造函数
| class Person { |
| String name = ""; |
| int age = 0; |
| |
| static Map<String, Person> _people = {}; |
| |
| Person(this.name, this.age); |
| |
| factory Person.Tom() { |
| var name = "Tom"; |
| var p = _people[name]; |
| if (p == null) { |
| p = Person(name, 0); |
| _people[name] = p; |
| } |
| return p; |
| } |
| } |
| var p = new Person.Tom(); |
自动调用父类无参构造函数
| class Person { |
| String name = ""; |
| int age = 0; |
| } |
| |
| class Student extends Person { |
| String number = ""; |
| } |
显式调用父类构造函数
| class Person { |
| String name = ""; |
| int age = 0; |
| |
| Person(this.name, age); |
| |
| Person.myself(int age) { |
| name = "Tom"; |
| this.age = age; |
| } |
| } |
| |
| class Student extends Person { |
| String number = ""; |
| |
| Student(String name, int age, String number): super(name, age) { |
| this.number = number; |
| } |
| |
| Student.myself(int age, String number): this.number = number, super.myself(age) { |
| } |
| } |
| var s1 = new Student("Tom", 10, "no.1"); |
| var s2 = new Student.myself(10); |
成员方法/实例方法
| class Person { |
| String name = ""; |
| int age = 0; |
| |
| String info() { |
| return "Person name is $name and age is $age."; |
| } |
| } |
| var s = new Student(); |
| s.info(); |
静态方法/类方法
| class Person { |
| String name = ""; |
| int age = 0; |
| |
| static readme() { |
| print("Person!"); |
| } |
| } |
继承
不支持多继承。
| class Person { |
| String name = ""; |
| int age = 0; |
| |
| String info() { |
| return "Person name is $name and age is $age."; |
| } |
| } |
| |
| class Student extends Person { |
| String number = ""; |
| } |
| var s = new Student(); |
| s.info(); |
函数重写
| class Person { |
| String name = ""; |
| int age = 0; |
| |
| String info() { |
| return "Person name is $name and age is $age."; |
| } |
| } |
| |
| class Student extends Person { |
| String number = ""; |
| |
| @override |
| String info() { |
| return super.info() + " Student number is $number."; |
| } |
| } |
运算符重写
| class Person { |
| String name = ""; |
| int age = 0; |
| |
| Person(this.name, this.age); |
| |
| Person operator +(Person p) { |
| var name = this.name + " and " + p.name; |
| var age = this.age + p.age; |
| return new Person(name, age); |
| } |
| } |
| var p1 = new Person("Tom", 10); |
| var p2 = new Person("Jerry", 9); |
| var p = p1 + p2; |
可重写的运算符有:
- <
- <=
-
-
=
- ==
-
-
-
- /
- ~/
- %
- &
- |
- ^
- ~
- <<
-
- []
- []=
抽象类与抽象方法
抽象类无法被实例化。
| abstract class Person { |
| String name = ""; |
| int age = 0; |
| |
| String info(); |
| } |
| |
| class Student extends Person { |
| String number = ""; |
| |
| @override |
| String info() { |
| return "Person name is $name and age is $age. Student number is $number."; |
| } |
| } |
接口
| class Person { |
| String name = ""; |
| int age = 0; |
| } |
| |
| abstract class Say { |
| int voice = 0; |
| |
| void say(); |
| } |
| |
| class Hello { |
| void hello() { |
| print("hello!"); |
| } |
| } |
| |
| class Student extends Person implements Say, Hello { |
| String number = ""; |
| |
| @override |
| int voice = 0; |
| |
| @override |
| void say() { |
| print("Person name is $name and age is $age. Student number is $number."); |
| } |
| |
| @override |
| void hello() { |
| print("hello!"); |
| say(); |
| } |
| } |
Mixin特性
| class Person { |
| String name = ""; |
| int age = 0; |
| } |
| |
| class Run { |
| void run() { |
| print("run!"); |
| } |
| } |
| |
| abstract class Say { |
| void say(); |
| } |
| |
| class Student extends Person with Run implements Say { |
| String number = ""; |
| |
| @override |
| void say() { |
| print("Person name is $name and age is $age. Student number is $number."); |
| } |
| } |
| var s = new Student(); |
| s.run(); |
可调用的类
| class Run { |
| call() { |
| print("run"); |
| } |
| } |
| |
| class Say { |
| call(String a, String b) { |
| print("say $a $b"); |
| } |
| } |
| var run = new Run(); |
| run(); |
| |
| var say = new Say(); |
| say("a", "b"); |
枚举
无法继承,无法使用Mixin特性,无法实例化。
| enum Grade { |
| grade1, |
| grade2 |
| } |
| var grade = Grade.grade1; |
| var index = Grade.grade1.index; |
类型定义
| typedef Repeat = String Function(String str); |
| typedef Name = String; |
| Name name = "Tom"; |
| Repeat f = (str) { |
| return str + ", " + str; |
| }; |
| var s = f(name); |
泛型
函数泛型
| String add<T>(T a, T b) { |
| return a.toString() + b.toString(); |
| } |
| |
| String addString<T extends String>(T a, T b) { |
| return a + b; |
| } |
| add(1, 2); |
| addString("a", "b"); |
类泛型
| class Add<T> { |
| String add(T a, T b) { |
| return a.toString() + b.toString(); |
| } |
| } |
| |
| class AddString<T extends String> { |
| String add(T a, T b) { |
| return a + b; |
| } |
| } |
| new Add().add(1, 2); |
| new AddString().add("a", "b"); |
异步
异步本质上是使用isolates运行模式进行并发。
| void main(List<String> args) { |
| work(); |
| print(2); |
| } |
| |
| work() async { |
| print(1); |
| var str = await takeTime(); |
| print(4); |
| print(str); |
| } |
| |
| Future<String> takeTime() async { |
| var str = await new Future.delayed(new Duration(seconds: 2), () { |
| print("..."); |
| print(3); |
| return "hello"; |
| }); |
| return str; |
| } |
在循环中异步
| void main(List<String> args) async { |
| Stream<String> stream = Stream.fromFuture(new Future.delayed(new Duration(seconds: 2), () { |
| print("..."); |
| print(2); |
| return "hello"; |
| })); |
| print(1); |
| await for (var str in stream) { |
| print(str); |
| } |
| print(3); |
| } |
注解/元数据
@deprecated
弃用。
| @deprecated |
| |
| void hello() { |
| } |
@override
重写。
| class Person { |
| String name = ""; |
| } |
| |
| class Student extends Person { |
| @override |
| String name = ""; |
| } |
@proxy
注释
单行注释
多行注释
文档注释
| |
| * This is a demo. |
| * |
| * Refer [say] for detail. |
| */ |
| void hello() { |
| } |
| |
| |
| |
| void say() { |
| } |
库
标识符除非以“_”开头,否则都是对库外可见的。
import内置库
| import 'dart:math'; |
| |
| void main(List<String> args) { |
| print(pi); |
| } |
import包库
| import 'package:flutter/material.dart'; |
import本地库
lib.dart:
| var _name = "lib.dart"; |
| |
| class Hello { |
| void hello() { |
| print("hello " + _name); |
| } |
| } |
main.dart:
| import 'lib.dart'; |
| |
| void main(List<String> args) { |
| new Hello().hello(); |
| } |
import-as
src/liba.dart:
| class Hello { |
| void helloA() { |
| print("hello a"); |
| } |
| } |
src/libb.dart:
| class Hello { |
| void helloB() { |
| print("hello b"); |
| } |
| } |
main.dart:
| import 'src/liba.dart' as liba; |
| import 'src/libb.dart' as libb; |
| |
| void main(List<String> args) { |
| new liba.Hello().helloA(); |
| new libb.Hello().helloB(); |
| } |
import-show
lib.dart:
| class Hello { |
| } |
| |
| class Say { |
| } |
| |
| class Run { |
| } |
main.dart:
| import 'lib.dart' show Hello, Say; |
| |
| void main(List<String> args) { |
| new Hello(); |
| new Say(); |
| } |
import-hide
lib.dart:
| class Hello { |
| } |
| |
| class Say { |
| } |
| |
| class Run { |
| } |
main.dart:
| import 'lib.dart' hide Run; |
| |
| void main(List<String> args) { |
| new Hello(); |
| new Say(); |
| } |
import-deferred as懒加载
lib.dart:
| class Hello { |
| hello() { |
| print("hello"); |
| } |
| } |
main.dart:
| import 'lib.dart' deferred as lib; |
| |
| void main(List<String> args) { |
| print("main"); |
| hello(); |
| } |
| |
| void hello() async { |
| await lib.loadLibrary(); |
| new lib.Hello().hello(); |
| } |
包
包目录结构如下:
- lib/:源代码目录。
- pubspec.yaml:配置文件。
flutter包的material.dart:
| export 'src/material/app.dart'; |
main.dart:
| import 'package:flutter/material.dart'; |
| |
| void main() { |
| runApp(const MyApp()); |
| } |
| |
| class MyApp extends StatelessWidget { |
| const MyApp({super.key}); |
| |
| @override |
| Widget build(BuildContext context) { |
| return const MaterialApp( |
| title: 'Flutter Demo' |
| ); |
| } |
| } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 本地部署 DeepSeek:小白也能轻松搞定!
· 传国玉玺易主,ai.com竟然跳转到国产AI
· 自己如何在本地电脑从零搭建DeepSeek!手把手教学,快来看看! (建议收藏)
· 我们是如何解决abp身上的几个痛点
· 如何基于DeepSeek开展AI项目
2022-12-22 FreeSWITCH学习笔记:Lua脚本