字符串
多行字符串
String str1 = """
你好
dart
""";
print(str1);
字符串拼接
String str2 = "你好";
String str3 = "dart";
print("$str2 $str3");
列表
指定类型创建
var l1=<String>["1","2"]
var l2=<int>[1,2,3];
移除 new List()
新版本不支持 new 创建列表
List.filled 创建固定长度列表
// 创建长度是 5,每个元素的值是 0 的列表,并自动推导为 int 类型
// 不可以增加元素
var l1= List.filled(5,0);
// 不可以修改长度
// l1.length = 0;
List.filled 指定类型创建列表
var l1= List<String>.filled(5,"你好");
字典
创建和获取
// 字面量方式直接创建
var m1 = {
"name": "dc",
"age": 30
};
// 中括号方式取值,不区分双引号 还是单引号
print(m1['name']);
print(m1["name"]);
// 不支持用 .name 的方式
// print(m1.name); 报错
通过 new Map() 创建
var m1 = new Map();
m1["name"] = "dc";
m1["age"] = 28;
is 类型判断
var m1 = 345;
if(m1 is int) {
print("int");
}else if (m1 is String) {
print("String");
}
算术运算符
取整 ~/
var m1 = 5;
print(m1 / 3); // 1.666666
print(m1 ~/ 3); // 1
赋值运算符
??=
a ??= b 如果 a 等于空, 将 b 的值赋予 a
var m1;
m1 ??= 5;
print(m1); // 5
var m2 = 6;
// m2 不等于空, 不会赋值
m2 ??= 5;
print(m2); // 6
??
a = b ?? c 如果 b 等于空,把 c 的值赋给 a
var m1;
var m2;
m1 = m2 ?? 5;
print(m1);
类型转换
字符串转 int
int.parse
var m = "123";
var m2 = int.parse(m);
print(m2 is int); // true
print(m2); // 123
字符串转 double
double.parse
var m = "123.2";
var m2 = double.parse(m);
print(m2 is double);
print(m2);
转 String
toString
空比较
var m;
// 不会报错,空值可以比较
print(m == 0); // false
print(m == null); // true
NaN
var m = 0 / 0;
// 不会报错
print(m); // Nan
print(m.isNaN); // true
方法
嵌套
void pa() {
print("a");
// 嵌套方法,作用在 pa() 内部
void pb() {
print("b");
}
pb();
}
void main() {
pa();
// 报错,超出作用域
pb();
}
省略返回类型,不建议
// 如果不知道方法的返回类型可以不写,但是建议写上
pa() {
return 3;
}
void main() {
print(pa());
}
可选参数
// 可选参数用 [] 包裹,并且允许为空
void pa(String name, [int ? age, String ? address]) {
print("name: $name");
if (age != null) {
print("age: $age");
}else{
print("age 未知");
}
if (address != null) {
print("address: $address");
}else{
print("address 未知");
}
}
void main() {
pa("张三", 30);
// name: 张三
// age: 30
// address 未知
}
默认参数
定义方法时,给可选参数设置默认值
void pa(String name, [int ? age, String address= "北京"]) {
print("name: $name");
if (age != null) {
print("age: $age");
}else{
print("age 未知");
}
if (address != null) {
print("address: $address");
}else{
print("address 未知");
}
}
void main() {
pa("张三");
}
输出:
name: 张三
age 未知
address: 北京
命名参数
// 命名参数,用{} 包裹,可以指定参数名赋值,而不按照顺序
void pa(String name, {int ? age, String ? address}) {
print("name: $name");
if (age != null) {
print("age: $age");
}else{
print("age 未知");
}
if (address != null) {
print("address: $address");
}else{
print("address 未知");
}
}
void main() {
// 命名参数可以跳过 age , 指定 address 的值
pa("张三", address: "上海");
// 可选参数,只能按照顺序赋值
}
方法作为参数传入
void fn1(){
print("fn1");
}
void fn2(){
print("fn2");
}
// 参数是个方法
void f3(fn){
// 调用传入的方法
fn();
print("fn3");
}
void main() {
f3(fn1);
f3(fn2);
}
输出:
fn1
fn3
fn2
fn3
类
访问属性的三种方法
推荐使用 this
访问
class Person{
int age = 10;
String name = "张三";
void out(){
print("$name: $age 岁");
print("${name}: ${age} 岁");
// 推荐
print("${this.name}: ${this.age} 岁");
}
}
默认构造方法的简写形式
默认构造方法只能有一个
class Person {
int age;
String name;
// 构造方法
// Person(int age, String name) {
// this.age = age;
// this.name = name;
// }
// 构造方法的简写形式
Person(this.age, this.name);
void getInfo() {
print("${this.name}: ${this.age} 岁");
}
}
void main() {
Person p1 = new Person(10, "张三");
p1.getInfo();
}
命名构造方法
命名构造方法可以有多个
class Person {
int age = 0;
String name = "";
// 默认构造方法的简写形式
// 只能有一个
Person(this.age, this.name);
// 命名构造方法
// 可以有多个
Person.one(int age){
this.age = age;
this.name = "李四";
}
// 命名构造方法的简写形式
Person.two(this.age){
this.name = "王二";
}
void getInfo() {
print("${this.name}: ${this.age} 岁");
}
}
void main() {
Person p1 = Person.one(20);
p1.getInfo();
Person p2 = Person.two(30);
p2.getInfo();
}
导入
lib/Person.dart
class Person {
int _age = 0;
String _name = "";
Person(this._age, this._name);
Person.one(int age){
this._age = age;
this._name = "李四";
}
void getInfo() {
print("${this._name}: ${this._age} 岁");
}
}
main.dart
// 导入同目录下的类
import 'lib/Person.dart';
void main() {
Person p1 = Person.one(20);
p1.getInfo();
}
重命名包
如果要导入的包有相同的类名,可以使用 as xx, 将该包重命名为 xx 使用时带上前缀:xx.Class
如下
import 'lib/Person1.dart';
import 'lib/Person2.dart' as lib;
void main() {
Person p = new Person("dc1", 10);
p.getInfo();
lib.Person p2 = new lib.Person("dc2", 10);
p2.getInfo();
}
部分引入
- 只导入需要的部分
- 隐藏不需要的部分
Tools.dart
void getName() {
print("get name");
}
void getAge() {
print("get age");
}
void cal() {
print("cal");
}
main.dart
// 只引入 getAge() cal() 方法
import 'lib/Tools.dart' show getAge, cal;
void main() {
cal();
getAge();
}
// 隐藏 cal() 方法
import 'lib/Tools.dart' hide cal;
void main() {
getAge();
getName();
}
私有属性 私有方法
下划线开头的属性和方法是私有的,只能在当前类中访问
class Person {
// 下划线开头的属性是私有属性,类外文件无法访问到
int _age = 0;
String _name = "";
Person(this._age, this._name);
Person.one(int age){
this._age = age;
this._name = "李四";
}
_run(){
}
void getInfo() {
print("${this._name}: ${this._age} 岁");
}
}
getter 和 setter
class Person {
int _age = 0;
// getter
get getAge {
return _age;
}
// setter
set setAge(int age) {
this._age = age;
}
}
main.dart
import 'lib/Person.dart';
void main() {
Person p1 = new Person();
// 给私有成员赋值
p1.setAge = 10;
// 获取私有成员的值
print(p1.getAge);
}
对象运算符
? 条件运算符
import 'lib/Person.dart';
void main() {
Person? p;
// 如果 p 等于空,则不调用 getInfo 方法
p?.getInfo(); // Nothing
Person? p1 = new Person("dc1", 20);
// p1 不等于空,会调用 getInfo 方法
p1?.getInfo();
}
is 类型判断
import 'lib/Person.dart';
void main() {
Person p = new Person("dc", 20);
print( p is Person) // true
}
as 类型转换
import 'lib/Person.dart';
void main() {
var p;
p = new Person("dc", 20);
(p as Person).getInfo();
}
.. 连缀
import 'lib/Person.dart';
void main() {
Person p = Person.empty();
p
..name = "dc10"
..age = 10
..getInfo();
// 等同于
// p.name = "dc10";
// p.age = 10;
// p.getInfo();
}
继承中的超级初始化器
class Animal {
String? name;
int? age;
Animal(String this.name, int this.age);
void printInfo() {
print("${name}: ${age}");
}
}
class Cat extends Animal {
// 超级初始化器
// 因为子类的构造方法中必须在第一行调用父类的构造方法,dart 直接将这以规则提升到语法层面。防止忘记
Cat(String name, int age) : super('', 0);
}
void main() {
Cat cat = new Cat("jonn", 2);
cat.printInfo();
}
mixin 混入
mixin A
关键词允许 A 类混入其他类中
class C with A
C 具有 A 的所有 public 的方法
- 实现了多继承的效果
- A 不能有构造方法
mixin class A {
String? aName;
// 不能有构造方法
// A(){}
void printA() {
print(aName);
}
void _printA1() {
print("私有方法");
}
}
mixin B {
String? bName;
void printB() {
print(bName);
}
}
// 不可以混入其他类中
class B1 {
}
class C with A, B {
String? cName;
void printC() {
print(cName);
}
}
void main() {
C c = new C();
c.aName = "a";
c.bName = "b";
c.cName = "c";
c.printA();
c.printB();
c.printC();
print(c is A); // true
print(c is B); // true
}
依赖
1. 依赖说明文件
根目录下 pubspec.yaml
2. 依赖声明
# 项目名称
name: study01
# 指定 sdk
environment:
sdk: "^3.5.0"
# 指定依赖版本
dependencies:
http: ^1.2.2
dio: ^5.7.0
3. 安装依赖
dart pub get
4. 用命令的方式安装依赖
dart pub add http
deps
用于显示当前 Package 使用的所有依赖项。
空安全,延迟初始化,参数不能为空
class Person {
// name 可以为空
String? name;
// 初始化对象时,sex 可以暂时为空,但在使用时,它不能为空
late String sex;
// age 不允许为空,也不可以延迟赋值
// 初始化对象时,age 必须有值
int age;
// age 不允许为空,所以在构造函数中要有 required 关键词,否则编译报错
// set 不允许为空,但可以延迟初始化,所以在构造函数中,可以不对 sex 赋值
// name 可以为空,所以不用加 required
Person({required this.age, this.name});
void setSex(String sex) {
this.sex = sex;
}
void getInfo() {
print("姓名:${this.name}");
print("年龄:${this.age}");
print("性别:${this.sex}");
}
}
void main() {
Person p = Person(age: 10);
// 在使用 sex 之前必须赋值,否则运行报错
p.setSex("sex");
p.getInfo();
}
常量
const 和 final
- const 是编译时常量, final 是运行时常量
- const 在声明变量时就要赋值,final 允许延迟赋值。
- 均只能赋值一次
void main() {
// final 声明的常量可以在运行时赋值,但只能赋值一次
final int a;
a = 1;
// 再次赋值会报错
// a = 2;
// const 声明的常量,在声明时就要赋值
const int b = 1;
// 不可以改变
// b = 2;
}
节省内存
被 const 修饰的构造函数,参数一样时,多次构造出来的对象占用同一个内存空间
identical(a,b)
判断 a b 的内存地址是否一样
class Person {
// 字段不可变
final int age;
// 常量构造函数,使用时才可以被 const 修饰
const Person(this.age);
}
void main() {
// 被 const 修饰的构造函数,参数一样时,构造出来的对象占用同一个内存空间
var p1 = const Person(10);
var p2 = const Person(10);
var p3 = const Person(20);
print(identical(p1, p2)); // true
print(identical(p1, p3)); //false
}
联系方式:dccmmtop@foxmail.com