Dart学习笔记:语法

本文更新于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 l = [1, "2", 1];

集合

var s = {1, "2"};

映射

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

for (var v in set) {
}

while

while (condition) {
}

do-while

do {
} while(condition);

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)模式下无效。

assert(flag);

异常

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();
}
print(Person.total);

构造函数

构造函数的执行顺序为:实例变量赋值 -> 初始化参数列表 -> 父类构造函数 -> 本类构造函数。

默认无参构造函数

class Person {
String name = "";
int age = 0;
}
var p1 = new Person();
var p2 = Person();

默认自动生成无参构造函数:

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 = "";
}
var s = new Student();

显式调用父类构造函数

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!");
}
}
Person.readme();

继承

不支持多继承。

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
// Should use Hello();
void hello() {
}

@override

重写。

class Person {
String name = "";
}
class Student extends Person {
@override
String name = "";
}

@proxy

注释

单行注释

// Comment.

多行注释

/*
Comment.
Comment.
Comment.
*/
/* Comment.
Comment.
Comment. */

文档注释

/**
* This is a demo.
*
* Refer [say] for detail.
*/
void hello() {
}
/// This is a demo.
/// Used by [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/:源代码目录。
    • src/:私有源代码目录。
  • 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'
);
}
}
posted @   garvenc  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 本地部署 DeepSeek:小白也能轻松搞定!
· 传国玉玺易主,ai.com竟然跳转到国产AI
· 自己如何在本地电脑从零搭建DeepSeek!手把手教学,快来看看! (建议收藏)
· 我们是如何解决abp身上的几个痛点
· 如何基于DeepSeek开展AI项目
历史上的今天:
2022-12-22 FreeSWITCH学习笔记:Lua脚本
点击右上角即可分享
微信分享提示