一. 打印
main(List<String> args) {
print('Hello World');
}
二. 声明变量
main(List<String> args) {
//1. 明确声明
String name = "name";
// 2. 类型推导(var/final/const)
//类型推导的方式虽然没有明确的指定变量的类型,但是变量是有自己明确的类型
//2.1 var 声明变量
var age = 20;
//2.2 final 声明常量
final height = 1.88;
//2.3 const 声明常量
const address = "浙江";
//2.4 final和const区别
//final 可以通过计算/函数获取一个值(运行期间来确定一个值)
//const 必须赋值 常量值(编译期间需要有一个确定的值)
//final 用的多一点
final date = DateTime.now();
}
三. 数据类型
3.1. 数字类型
整数用int
浮点数用double
Dart中的int
和double
可表示的范围并不是固定的,它取决于运行Dart的平台。
// 1.整数类型int
int age = 18;
int hexAge = 0x12;
print(age);
print(hexAge);
// 2.浮点类型double
double height = 1.88;
print(height);
3.2. 字符串
3.2.1. 字符串定义
Dart字符串是UTF-16编码单元的序列。可以使用单引号或双引号创建一个字符串:
// 1.定义字符串的方式
var s1 = 'Hello World';
var s2 = "Hello Dart";
var s3 = 'Hello\'Fullter';
var s4 = "Hello'Fullter";
可以使用三个单引号或者双引号表示多行字符串:
// 2.表示多行字符串的方式
var message1 = '''
哈哈哈
呵呵呵
嘿嘿嘿''';
字符串和其他变量或表达式拼接: 使用${expression}, 如果表达式是一个标识符, 那么{}可以省略:
// 3.拼接其他变量
var name = 'coder';
var age = 18;
var height = 1.88;
var message = "name is ${name}, type is ${name.runtimeType}";
print('my name is ${name}, age is $age, height is $height');
//强调:${变量},那么{} 可以省略
var message2 = "name is $name, type is ${name.runtimeType}";
3.2.2. 字符串和数字之间的转化
// 字符串和数字转化
// 1.字符串转数字
var one = int.parse('111');
var two = double.parse('12.22');
print('${one} ${one.runtimeType}'); // 111 int
print('${two} ${two.runtimeType}'); // 12.22 double
// 2.数字转字符串
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
3.3 集合类型
3.3.1. 集合类型的定义
- 列表List
- 集合Set
- 映射Map
1) List
可以这样来定义:
// List定义
// 1.使用类型推导定义
var letters = ['a', 'b', 'c', 'd'];
print('$letters ${letters.runtimeType}');
// 2.明确指定类型
List<int> numbers = [1, 2, 3, 4];
print('$numbers ${numbers.runtimeType}');
2) set
可以这样来定义:
Set
和List
最大的两个不同就是:Set
是无序的,并且元素是不重复的。
// Set的定义
// 1.使用类型推导定义
var lettersSet = {'a', 'b', 'c', 'd'};
print('$lettersSet ${lettersSet.runtimeType}');
// 2.明确指定类型
Set<int> numbersSet = {1, 2, 3, 4};
print('$numbersSet ${numbersSet.runtimeType}');
3) Map
是我们常说的字典类型,它的定义是这样的:
// Map的定义
// 1.使用类型推导定义
var infoMap1 = {'name': 'why', 'age': 18};
print('$infoMap1 ${infoMap1.runtimeType}');
// 2.明确指定类型
Map<String, Object> infoMap2 = {'height': 1.88, 'address': '北京市'};
print('$infoMap2 ${infoMap2.runtimeType}');
3.3.2. 集合的常见操作
1)获取长度:length
// 获取集合的长度
print(letters.length);
print(lettersSet.length);
print(infoMap1.length);
2) 添加/删除/包含操作
- 并且,对
List
来说,由于元素是有序的,它还提供了一个删除指定索引位置上元素的方法;
// 添加/删除/包含元素
numbers.add(5);
numbersSet.add(5);
print('$numbers $numbersSet');
numbers.remove(1);
numbersSet.remove(1);
print('$numbers $numbersSet');
print(numbers.contains(2));
print(numbersSet.contains(2));
// List根据index删除元素
numbers.removeAt(3);
print('$numbers');
3) Map
的操作
- 由于它有key和value,因此无论是读取值,还是操作,都要明确是基于key的,还是基于value的,或者是基于key/value对的。
// Map的操作
// 1.根据key获取value
print(infoMap1['name']); /jay
// 2.获取所有的entries
print('${infoMap1.entries} ${infoMap1.entries.runtimeType}'); // (MapEntry(name: jay), 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}'); // (jay, 18) _CompactIterable<Object>
// 5.判断是否包含某个key或者value
print('${infoMap1.containsKey('age')} ${infoMap1.containsValue(18)}'); // true true
// 6.根据key删除元素
infoMap1.remove('age');
print('${infoMap1}'); // {name: jay}
3.4. Object 和 dynamic
- Object 调用方法时,编译时会报错;
- dynamic调用方法时,编译时不报错,但是运行时会存在安全隐患;
//Object obj1 = "Jay";
//print(obj1.substring(1)); //编译报错
//明确声明
dynamic obj2 = "Cat";
print(obj2.substring(1)); //正常
dynamic obj3 = 123;
print(obj3.substring(1)); //编译通过,运行时会崩溃,因为int没有"substing"这个方法
1. dynamic 声明变量时是一个明确的声明
四. 函数
4.1. 函数的基本定义
Dart是一种真正的面向对象语言,所以即使函数也是对象,所以也有类型, 类型就是Function。
这也就意味着函数可以作为变量定义或者作为其他函数的参数或者返回值.
4.1.1. 函数的定义方式
返回值 函数的名称(参数列表) {
函数体
return 返回值
}
int sum(num num1, num num2) {
return num1 + num2;
}
//返回值类型是可以省略的(开发中不推荐)
sum(num num1, num num2) {
return num1 + num2;
}
4.2函数的可选参数
函数的参数可以分成两类:
- 必选参数
void sayHello1 (String name) {
print(name);
}
- 可选参数:位置可选参数、命名可选参数;
强调:只有可选参数才可以有默认值;
main(List<String> args) {
// 顺序是有要求的
sayHello2("test", 18, 1.88);
}
// 位置可选参数:[int age, double height]
// 实参和形参在进行匹配时,是根据位置的匹配
void sayHello2 (String name,[int age, double height]) {
print(name);
}
---
main(List<String> args) {
// 必须写参数名
sayHello2("test", age :18, height: 1.88);
// 后面的参数位置可变
sayHello2("test", height: 1.88, age :18);
// 后面的参数可省略
sayHello2("test", height: 1.88);
}
// 命名可选参数 {int age, double height}
// 开发中用的最多
void sayHello2 (String name,{int age, double height}) {
print(name);
}
void sayHello3 (String name,{int age = 10, double height}) {
print(name);
}
4.3 函数是一等公民
4.3.1 函数可以作为另外一个函数的参数
main(List<String> args) {
// 1.将函数赋值给一个变量
var bar = foo;
print(bar);
// 2.将函数作为另一个函数的参数
test(foo);
// 3.将函数作为另一个函数的返回值
var func = getFunc();
func('kobe');
}
// 1.定义一个函数
void foo(String name) {
print('传入的name:$name');
}
// 2.将函数作为另外一个函数的参数
void test(Function func) {
func('coderwhy');
}
// 3.将函数作为另一个函数的返回值
getFunc() {
return foo;
}
开发中实际应用
typedef Calculate = int Function (int num1, int num2);
void test(Calculate calc) {
calc(20, 30);
}
4.3.2 匿名函数
大部分我们定义的函数都会有自己的名字, 比如前面定义的foo、test函数等等。
但是某些情况下,给函数命名太麻烦了,我们可以使用没有名字的函数,这种函数可以被称之为匿名函数( anonymous function),也可以叫_lambda_或者_closure_。
- 当函数体只有一行代码时,可以 使用箭头函数
// 匿名函数格式
//
test((){
print("匿名函数被调用");
});
// 箭头函数格式
test(() = print ("箭头函数被调用"));
main(List<String> args) {
// 1.定义数组
var movies = ['盗梦空间', '星际穿越', '少年派', '大话西游'];
// 2.使用forEach遍历: 有名字的函数
printElement(item) {
print(item);
}
movies.forEach(printElement);
// 3.使用forEach遍历: 匿名函数
movies.forEach((item) {
print(item);
});
// 箭头函数
movies.forEach((item) => print(item));
}