一.Dart变量声明方式:
方式1:明确声明(Explicit)
变量类型 变量名称 = 赋值;
String wsName = 'ws';
int wsAge = 29;
double wsHeight = 1.78;
print('${wsName}, ${wsAge}, ${wsHeight}'); // ws,29,1.78
//注意事项: 定义的变量可以修改值, 但是不能赋值其他类型
//name = 20;报错
方式2:类型推导(Type Inference)
var/dynamic/const/final 变量名称 = 赋值;
2.1 var的使用
var wsAge = 20;
print(wsAge.runtimeType); //runtimeType用于获取变量当前的类型 int
// wsAge = "abc";//报错 类型不匹配(wsAge在声明的时候已经明确了类型 不可以将String赋值给一个int类型)
//类型推导的方式虽然没有明确的指定变量的类型,但是变量是有自己的明确的类型
2.2.final声明常量
final wsHeight = 1.78;
// wsHeight = 2.00; 报错 常量赋值之后不能修改
2.3.const声明常量
const wsAddress = "深圳市";
// wsAddress = "郑州市"; 报错 常量赋值之后不能修改
*final和const的区别*
//const必须赋一个常量值(编译期间必须有一个确定的值)
//final可以通过计算/函数获取一个值(运行期间来确定一个值)
// const currentTime = DateTime.now(); // 报错
final currentTime = DateTime.now();
二.数据类型:
1. 数字类型
// 1.整数类型int
int wsAge = 30;
print(wsAge);//30
// 2.浮点类型double
double wsHeight = 1.78;
print(wsHeight);//1.78
//注意:Dart中的int和double可表示的范围并不是固定的,它取决于运行Dart的平台。
-
字符串和数字之间的转化:
// 1.字符串转数字
var wsInt = int.parse('1');
var wsDouble = double.parse('1.1');
print('${wsInt} ${wsInt.runtimeType}'); // 1 int
print('${wsDouble} ${wsDouble.runtimeType}'); // 1.1 double
// 2.数字转字符串
var wsInt1 = 123;
var wsDouble1 = 123.456;
var wsStr1 = wsInt1.toString();
var wsStr2 = wsDouble1.toString();
var wsStr3 = wsDouble1.toStringAsFixed(2); // 保留两位小数
print('${wsStr1} ${wsStr1.runtimeType}'); // 123 String
print('${wsStr2} ${wsStr2.runtimeType}'); // 123.456 String
print('${wsStr3} ${wsStr3.runtimeType}'); // 123.46 String
2. 布尔类型
Dart提供了一个bool的类型, 取值为true和false
var isFlag = true;
print('$isFlag ${isFlag.runtimeType}');
/**
* 注意:
* 1.Dart中不能判断非0即真, 或者非空即真
* 2.Dart的类型安全性意味着您不能使用if(非booleanvalue)或assert(非booleanvalue)之类的代码。
*/
//if判断报错 Dart中不能判断非0即真, 或者非空即真 if表达式必须是bool类型的
// var flag1 = "abc";
// //if判断报错
// if (flag1) {
// print('执行代码');
// }
3.字符串类型
Dart字符串是UTF-16编码单元的序列。您可以使用单引号或双引号创建一个字符串:
//1.定义字符串的方式
var wsStr1 = 'Hello World';
var wsStr2 = "Hello Dart";
//2.表示多行字符串的方式
var wsStr3 = """
abc
cba
bac
""";
//3.字符串和表达式进行拼接:如果${},括号中是变量 而不是表达式 那么{}可以省略
var name = "ws";
var age = 29;
var height = 1.78;
var message = "my name is ${name}, age is ${age}, height is ${height}";
var message1 = "name is ${name}, type is ${name.runtimeType}";
var message2 = "my name is $name, age is $age, height is $height";
print(message);
print(message1);
print(message2);
4. 集合类型
对于集合类型,Dart则内置了最常用的三种:List / Set / Map。
//1.List列表(相当于iOS中的数组)
//1.1:使用类型推导定义
var wsList1 = ["abc", "cba", "nba"];
print(wsList1);
print(wsList1[0]);
print("wsList1 type is ${wsList1.runtimeType}"); //wsList1 type is List<String>
//1.2:明确指定类型
List<int> wsList2 = [11, 22, 33, 44];
print('$wsList2 ${wsList2.runtimeType}');
//2.set定义
//2.1:使用类型推导定义
var wsSet1 = {'a', 'b', 'c', 'd'};
print('$wsSet1 ${wsSet1.runtimeType}');
// 2.2:明确指定类型
Set<int> wsSet2 = {11, 22, 33, 44};
print('$wsSet2 ${wsSet2.runtimeType}');
//注意:Set和List最大的两个不同就是:Set是无序的,并且元素是不重复的。
//3.映射Map(相当于iOS中的字典)
//3.1:使用类型推导定义
var wsMap1 = {"name": "ws", "age": 29};
print(wsMap1);
print(wsMap1["name"]);
print(
"wsMap1 type : ${wsMap1.runtimeType}"); //wsMap1 type : _InternalLinkedHashMap<String, Object>
//3.2:明确指定类型
Map<String, Object> wsMap2 = {'height': 1.78, 'address': '郑州市'};
print('$wsMap2 ${wsMap2.runtimeType}');
//4.集合的常见操作
//4.1获取集合的长度(所有集合都支持的获取长度的属性length)
print(wsList1.length);
print(wsSet1.length);
print(wsMap1.length);
//4.2:添加/删除/包含操作(对List来说:由于元素是有序的,它还提供了一个删除指定索引位置上元素的方法)
wsList2.add(55);//添加元素
wsSet2.add(55);
print('$wsList2 $wsSet2');
wsList2.remove(11);//移除某个元素
wsSet2.remove(11);
print('$wsList2 $wsSet2');
print(wsList2.contains(22));//是否包含某个元素
print(wsSet2.contains(22));
wsList2.removeAt(3);// List根据index删除元素
print('$wsList2');
//4.3:是Map的操作(由于它有key和value,因此无论是读取值,还是操作,都要明确是基于key的,还是基于value的,或者是基于key/value对的.)
// 1.根据key获取value
print(wsMap1['name']);// ws
// 2.获取所有的entries
print('${wsMap1.entries}');//(MapEntry(name: ws), MapEntry(age: 29))
// 3.获取所有的keys
print('${wsMap1.keys}');//(name, age)
// 4.获取所有的values
print('${wsMap1.values};');//(ws, 29)
// 5.判断是否包含某个key或者value
print('${wsMap1.containsKey('age')} ${wsMap1.containsValue(29)}');// true true
// 6.根据key删除元素
wsMap1.remove('age');
print('${wsMap1}');// {name: ws}
三.函数:
1. 函数的基本定义
Dart是一种真正的面向对象语言,所以即使函数也是对象,所有也有类型, 类型就是Function。
这也就意味着函数可以作为变量定义或者作为其他函数的参数或者返回值.
//函数的定义方式:
返回值 函数的名称(参数列表) {
函数体
return 返回值
}
main(List<String> args) {
print(sum(20, 30)); //50
}
int sum(int num1, int num2) {
return num1 + num2;
}
-
箭头函数
条件: 如果函数中只有一个表达式(函数体只有一行代码的时候), 那么可以使用箭头语法(arrow syntax),注意, 这里面只能是一个表达式, 不能是一个语句
sum1(num1, num2) => num1 + num2;
//等价于
int sum(int num1, int num2) {
return num1 + num2;
}
2. 函数的参数问题
函数的参数可以分成两类: 必须参数和可选参数
1.必须按参数:必须参数.
2.可选参数可以分为: 命名可选参数 和 位置可选参数
定义方式:
命名可选参数: {param1, param2, ...}
位置可选参数: [param1, param2, ...]
注意:只有可选参数才可以有默认值
main(List<String> args) {
//必选参数
// sayHello1()//报错
sayHello1("abc");
//位置可选参数
// sayHello2("why");
sayHello2("why", 16, 16.8);
//命名可选参数
// sayHello3("ccc");
// sayHello3("ccc", age: 20);
// sayHello3("ccc", height: 20.1 ,age: 20);
sayHello3("ccc", age: 20, height: 20.1);
}
//必选参数:必须传
void sayHello1(String name) {
print(name);
}
//可选参数可以分为: 命名可选参数 和 位置可选参数
//位置可选参数(实参和形参在进行匹配时,是根据位置的匹配)
void sayHello2(String name, [int age = 1, double height = 2.0]) {
print(name);
print(age);
print(height);
}
//命名可选参数
void sayHello3(String name, {int age = 1, double height = 2.0}) {
print(name);
print(age);
print(height);
}
3. 函数是一等公民
在很多语言中, 函数并不能作为一等公民来使用, 比如Java/OC. 这种限制让编程不够灵活, 所以现代的编程语言基本都支持函数作为一等公民来使用, Dart也支持.这就意味着你可以将函数赋值给一个变量, 也可以将函数作为另外一个函数的参数或者返回值来使用.
-
函数作为参数
main(List<String> args) {
//1.将函数赋值给一个变量
var wsF = bar;
//2.函数可以作为另外一个函数的参数
test(bar);
//传入匿名函数
test(() {
print("匿名函数被调用");
});
//dart匿名函数的写法
// (参数列表) {函数体};
//箭头函数:(条件:函数体只有一行的代码)
test(() => print("箭头函数被调用"));
}
//2.函数可以作为另外一个函数的参数
void test(Function foo) {
foo();
}
void bar() {
print("bar函数被调用");
}
-
函数作为返回值
/**
* dart匿名函数的写法
* (参数列表) {函数体};
*
* 箭头函数条件:函数体只有一行代码的时候
*
* 所有函数都返回一个值。如果没有指定返回值,则语句返回null;隐式附加到函数体。
*
* dart中的词法有自己明确的作用域范围,它是根据代码的结构({})来决定作用域范围
* 的优先使用自己作用域中的变量,如果没有找到,则一层层向外查找。
*
*/
main(List<String> args) {
//带参数的函数作为参数
test1((String abc) {
print(abc);
});
//封装带参数/返回值的函数作为参数
test2((num1, num2) {
print(num1 + num2); //3
return num1 + num2;
});
//封装带参数/返回值的函数作为参数(typedef)
test3((num1, num2) {
print(num1 + num2); //30
return num1 + num2;
});
//函数作为返回值
var demo1 = demo();
var result = demo1(20, 30);
print(result); //600
}
//函数可以作为另外一个函数的参数
//封装test函数,要求:传入一个函数
void test1(Function foo) {
foo("why");
}
//封装带参数/返回值的函数作为参数
void test2(int foo(int num1, int num2)) {
foo(1, 2);
}
//封装带参数/返回值的函数作为参数(typedef)
//函数签名
typedef Calculate = int Function(int num1, int num2);
void test3(Calculate calc) {
calc(10, 20);
}
//函数作为返回值
Calculate demo() {
return (num1, num2) {
return num1 * num2;
};
}
4.运算符:
这里只列出来相对其他语言比较特殊的运算符,因为某些运算符太简单了,比如+、-、+=、==等等都是和其它语言一样.
1. 除法/、整除~/、取模运算%、赋值操作??=、条件运算符??
main(List<String> args) {
//除法、整除、取模运算
ws_subtractingAction();
//赋值运算符
ws_AssignmentOperatorAction();
}
//除法、整除、取模运算
ws_subtractingAction() {
var num = 7;
print(num / 3); // 除法操作, 结果2.3333..
print(num ~/ 3); // 整除操作, 结果2;
print(num % 3); // 取模操作, 结果1;
}
/**
* 赋值运算符:
* 1.当变量为null时,使用后面的内容进行赋值。
* 2.当变量有值时,使用自己原来的值。
* ??=
* 当name1初始化为ws时,结果为ws,当初始化为null时,赋值了newWs
*
*
*
* 条件运算符:
* 1.如果expr1是null,则返回expr2的结果;
* 2.如果expr1不是null,直接使用expr1的结果。
*
* ?? (类似三目运算符)
* ??前面数据有值, 那么就使用??前面的数据
* ??前面的数据为null, 那么就使用后面的值
*/
ws_AssignmentOperatorAction() {
// ??=
// var name1 = "ws";
// var name1;
var name1 = null;
name1 ??= "newWs";
// print(name1); //ws
print(name1); //newWs
// ??
var name2 = null;
var temp = name2 ?? "zz";
print(temp); //zz
}
2.级联语法:..
main(List<String> args) {
// Person p = Person();
// var p = Person();
// print(p.runtimeType); //Person
// p.name = "ws";
// p.run();//running
// p.eat();//eating
//级联运算符
var p1 = Person()
..name = "ws1"
..run() //running
..eat(); //eating
print(p1.runtimeType); //Person
}
class Person {
String name = "";
void run() {
print("running");
}
void eat() {
print("eating");
}
}