一、定义变量
1.1 声明变量
变量类型 变量名称 = 赋值
示例:
String name = 'coderwhy';int age = 18;double height = 1.88;
1.2 类型推导
var/dynamic/const/final 变量名称 = 赋值;
// var
var name = 'coderwhy';
name = 'kobe'; // 同类型
// dynamic
dynamic name = 'coderwhy';
name = 18; // 可以不同类型 不建议使用
// final和const都是用于定义常量的, 定义之后值都不可以修改
final name = 'coderwhy';
const age = 18;
final和const区别
- const在赋值时, 赋值的内容必须是在编译期间就确定下来的
- final在赋值时, 可以动态获取
String getName() {
return 'coderwhy';
}
main(List<String> args) {
const name = getName(); // 错误, 因为要执行函数才能获取到值
final name = getName(); // 正确
}
二、数据类型
2.1 数字类型
int age = 18;
double height = 1.88;
字符串和数字之间的转化:
// 字符串转数字
var one = int.parse('111');
var two = double.parse('12.22');
print('${one} ${one.runtimeType}'); // 111 int
print('${two} ${two.runtimeType}'); // 12.22 double
// 数字转字符串
var num1 = 123;
var num2 = 123.456;
var num1Str = num1.toString();
var num2Str = num2.toString();
var num2StrD = num2.toStringAsFixed(2); // 保留两位小数
print('${num1Str} ${num1Str.runtimeType}'); // 123 String
print('${num2Str} ${num2Str.runtimeType}'); // 123.456 String
print('${num2StrD} ${num2StrD.runtimeType}'); // 123.46 String
2.2 布尔类型
布尔类型中,Dart提供了一个bool的类型, 取值为true和false
var isFlag = true;
print('$isFlag ${isFlag.runtimeType}'); // true bool
注: Dart中不能判断非0即真, 或者非空即真
var message = 'Hello Dart';
// 错误
if (message) {
print(message)
}
2.3 字符串类型
// 1.定义字符串的方式
var s1 = 'Hello World';
// 2.表示多行字符串的方式
var message1 = '''
哈哈哈
呵呵呵
嘿嘿嘿''';
// 3.拼接其他变量
var name = 'coderwhy';
var age = 18;
var height = 1.78;
print('my name is ${name}, age is $age, height is $height');
2.3 集合类型
2.3.1 定义 -- List/Set/Map
- List
// List定义
// 1.使用类型推导定义
var letters = ['a', 'b', 'c', 'd'];
print('$letters ${letters.runtimeType}'); // [a, b, c, d] List<String>
// 2.明确指定类型
List<int> numbers = [1, 2, 3, 4];
print('$numbers ${numbers.runtimeType}'); // [1, 2, 3, 4] List<int>
// 扩展操作符
var list = [1, 2, 3];
var list2 = [0, ...list];
print('$list2 ${list2.runtimeType}'); // [1, 2, 3, 4] List<int>
// 空感知扩展操作符
var list1;
var list4 = [0, ...?list1];
print('$list4 ${list4.runtimeType}');// [0] List<dynamic>
注:扩展操作符(...)和 空感知扩展操作符(...?)提供了一种将多个元素插入集合的简洁方法
- Set 一组特定元素的无序集合
// 1.使用类型推导定义
var lettersSet = {'a', 'b', 'c', 'd'};
print('$lettersSet ${lettersSet.runtimeType}'); // {a, b, c, d} _Set<String>
// 2.明确指定类型
Set<int> numbersSet = {1, 2, 3, 4};
print('$numbersSet ${numbersSet.runtimeType}'); // {1, 2, 3, 4} _Set<int>
注:Set和List最大的两个不同就是:Set是无序的,并且元素是不重复的
- Map 常说的字典类型
// 1.使用类型推导定义
var infoMap1 = {'name': 'why', 'age': 18};
print('$infoMap1 ${infoMap1.runtimeType}');
// {name: why, age: 18} _Map<String, Object>
// 2.明确指定类型
Map<String, Object> infoMap2 = {'height': 1.88, 'address': '北京市'};
print('$infoMap2 ${infoMap2.runtimeType}');
// {name: why, age: 18} _Map<String, Object>
2.3.2 常见基础操作 -- List/Set/Map
- length
var letters = ['a', 'b', 'c', 'd'];
var lettersSet = {'a', 'b', 'c', 'd'};
Map<String, Object> infoMap2 = {'height': 1.88, 'address': '北京市'};
print(letters.length); // 4
print(lettersSet.length); // 4
print(infoMap2.length); // 2
- List/Set 的添加、删除、包含
var letters = ['a', 'b', 'c', 'd'];
var lettersSet = {'a', 'b', 'c', 'd'};
// 增加
letters.add('e');
lettersSet.add('e');
print(letters);
print(lettersSet);
// 删除
letters.remove('d');
lettersSet.remove('d');
print(letters);
print(lettersSet);
// 包含
print(letters.contains('a'));
print(lettersSet.contains('a'));
// list 根据index删除
letters.removeAt(0);
print(letters);
- Map操作
var infoMap1 = {'name': 'why', 'age': 18};
// 1.根据key获取value
print(infoMap1['name']); // why
// 2.获取所有的entries
print('${infoMap1.entries} ${infoMap1.entries.runtimeType}'); // (MapEntry(name: why), MapEntry(age: 18)) MappedIterable<String, MapEntry<String, Object>>
// 3.获取所有的keys
print('${infoMap1.keys} ${infoMap1.keys.runtimeType}'); // (name, age) _CompactIterable<String>
// 4.获取所有的values
print('${infoMap1.values} ${infoMap1.values.runtimeType}'); // (why, 18) _CompactIterable<Object>
// 5.判断是否包含某个key或者value
print('${infoMap1.containsKey('age')} ${infoMap1.containsValue(18)}'); // true true
// 6.根据key删除元素
infoMap1.remove('age');
print('${infoMap1}'); // {name: why}
三、函数
3.1 基本定义
函数的定义方式:
返回值 函数的名称(参数列表) {
函数体
return 返回值
}
int sum(num num1, num num2) {
return num1 + num2;
}
箭头函数
sum(num1, num2) => num1 + num2; // 函数体内只包含一个表达式
3.2 参数
参数可以分为:必选参数、可选参数。可选参数又分为命名可选参数、位置可选参数。
命名可选参数: {param1, param2, ...}
位置可选参数: [param1, param2, ...]
命名可选参数
// 命名可选参数
printInfo1(String name, {int? age, double? height}) {
print('name=$name age=$age height=$height');
}
// 调用printInfo1函数
printInfo1('why'); // name=why age=null height=null
printInfo1('why', age: 18); // name=why age=18 height=null
printInfo1('why', age: 18, height: 1.88); // name=why age=18 height=1.88
printInfo1('why', height: 1.88); // name=why age=null height=1.88
位置可选参数
// 定义位置可选参数
printInfo2(String name, [int? age, double? height]) {
print('name=$name age=$age height=$height');
}
// 调用printInfo2函数
printInfo2('why'); // name=why age=null height=null
printInfo2('why', 18); // name=why age=18 height=null
printInfo2('why', 18, 1.88); // name=why age=18 height=1.88
命名可选参数, 可以指定某个参数是必传的(使用@required)
// 命名可选参数的必须
printInfo3(String name, {int? age, double? height, required String address}) {
print('name=$name age=$age height=$height address=$address');
}
printInfo3('why',address: 'XX省XX市', age: 18); // name=why age=18 height=null address=XX省XX市
参数默认值
// 参数的默认值
printInfo4(String name, {int age = 18, double height = 1.88}) {
print('name=$name age=$age height=$height');
}
printInfo4('why', age: 20); // name=why age=20 height=1.88
注:只有可选参数才可以有默认值, 必须参数不能有默认值
3.3 函数是一等公民
可以将函数赋值给一个变量,也可以将函数作为另外一个函数的参数或者返回值来使用
main(List<String> args) {
// 1.将函数赋值给一个变量
var bar = foo;
print(bar); // Closure: (String) => dynamic from Function 'foo': static.
// 2.将函数作为另一个函数的参数
test(foo); // 传入的name:coderwhy
// 3.将函数作为另一个函数的返回值
var func = getFunc();
func('kobe'); // 传入的name:kobe
}
// 1.定义一个函数
foo(String name) {
print('传入的name:$name');
}
// 2.将函数作为另外一个函数的参数
test(Function func) {
func('coderwhy');
}
// 3.将函数作为另一个函数的返回值
getFunc() {
return foo;
}
3.4 匿名函数
没有名字的函数,称为匿名函数
// 1.定义数组
var movies = ['盗梦空间', '星际穿越', '少年派', '大话西游'];
// 2.使用forEach遍历: 有名字的函数
printElement(item) {
print(item);
}
movies.forEach(printElement); // 盗梦空间 星际穿越 少年派 大话西游
// 3.使用forEach遍历: 匿名函数
movies.forEach((item) {
print(item); // 盗梦空间 星际穿越 少年派 大话西游
});
// 箭头缩写法
movies.forEach((item) => print(item)); // 盗梦空间 星际穿越 少年派 大话西游
3.5 词法作用域
优先使用自己作用域中的变量,如果没有找到,则一层层向外查找
var name = 'global';
main(List<String> args) {
var name = 'main';
void foo() {
var name = 'foo';
print(name);
}
foo();
}
3.6 词法闭包
makeAdder(num addBy) {
return (num i) {
return i + addBy;
};
}
var adder2 = makeAdder(2);
print(adder2(10)); // 12
print(adder2(6)); // 8
var adder5 = makeAdder(5);
print(adder5(10)); // 15
print(adder5(6)); // 11
3.7 返回值问题
main(List<String> args) {
print(foo()); // null
}
foo() {
print('foo function');
}
四、运算符
4.1 算数以及关系运算符
+ : 加 、 - : 减、-表达式 : 反转 、 * : 乘、
/ : 除 、 ~/ : 除并取整、%: 取模
== != > < >= <=
print(2 + 3 == 5); // true
print(2 - 3 == -1); // true
print(2 * 3 == 6); // true
print(5 / 2 == 2.5); // true
print(5 ~/ 2 == 2); // true
print(5 % 2 == 1); // true
print('5/2 = ${5 ~/ 2} r ${5 % 2}' == '5/2 = 2 r 1');// true
4.2 ?== 赋值操作
- 当变量为null时,使用后面的内容进行赋值。
- 当变量有值时,使用自己原来的值
main(List<String> args) {
var name1 = 'coderwhy';
print(name1);
// var name2 = 'kobe';
var name2 = null;
name2 ??= 'james';
print(name2); // 当name2初始化为kobe时,结果为kobe,当初始化为null时,赋值了james
}
4.3 条件表达式
条件 ? 表达式 1 : 表达式 2
如果条件为 true,执行表达式 1并返回执行结果,否则执行表达式 2 并返回执行结果。
表达式 1 ?? 表达式 2
如果表达式 1 为非 null 则返回其值,否则执行表达式 2 并返回其值。
var temp = null;
var name = temp ?? 'kobe';
print(name); // kobe
4.4 级联运算符
级联运算符 (.., ?..) 可以让你在同一个对象上连续调用多个对象的变量或方法
class Person {
late String name;
void run() {
print("${name} is running");
}
void eat() {
print("${name} is eating");
}
void swim() {
print("${name} is swimming");
}
}
main(List<String> args) {
final p1 = Person();
p1.name = 'why1';
p1.run();
p1.eat();
p1.swim();
final p2 = Person()
..name = "why2"
..run()
..eat()
..swim();
}
五、流程控制
if和elsefor循环while和do-while循环break和continueswitch和caseassert
和其他语言类似