Dart基本语法
文章目录
声明变量
var
var实际上是编译期抛给我们的“语法糖”,一旦被编译,
编译期会自动匹配var 变量的实际类型,并用实际类型来替换该变量的申明
- var : 【编译期】确定【变量类型】
void main(){
var a = "Hello Dart!";
print(a);
var b = 520;
b = 'hello'; //报错
print(b);
var c = 520.0;
print(c);
}
dynamic
dynamic被编译后,实际是一个 object类型,
只不过编译器会对dynamic类型进行特殊处理,
让它在编译期间不进行任何的类型检查,而是将类型检查放到了运行期。
- dynamic : 【运行期】确定【变量类型】
dynamic b = 520;
b = 'hello';
print(b);
Object类型
在Dart中所有东西都是对象,都继承于Object, 所以可以使用Object可以定义任何的变量,而且赋值后,类型也可以更改。但只能使用Object类的方法。
Object color = 'black';
color = 0xff000000;//运行正常,0xff000000类型是int, int也继承于Object
常量
const必须根据可在编译时计算的数据创建它们。
const对象无法访问运行时需要计算的任何内容。
1+2是一个合法的const表达式,但new DateTime.now()不是(合法的const表达式)
final
final必须初始化,只能赋值一次,且不能修改值,赋值可以是常量也可以是变量。
- final :【运行期】确定【常量值】
final s = "hello dart";
final date = new DateTime.now();
print(date);
print(s);
const
const必须初始化,只能赋值一次,且不能修改值,赋值必须是常量。
- const :【编译期】确定【常量值】
const a = 1+2;
print(a);
数据类型
字符串类型–String
在Dart中支持单引号、双引号、三引号以及$字符串模板。
String str = "hello";
String name = 'Purcell Huang';
print(str);
String address = '''广东
茂名
XXX''';
String s = """广东
茂名
XXX""";
print("这是我的住址 $address");
print(address);
int a = 100;
int b = 200;
print("a + b = ${a+b}");
String的一些常用方法:
String url = "https://blog.csdn.net/weixin_37267014";
print(url.split("://")[0]); //字符串分割split方法,类似Java
print(url.substring(3, 9)); //字符串截取substring方法, 类似Java
print(url.codeUnitAt(0)); //取当前索引位置字符的UTF-16码
print(url.startsWith("https")); //当前字符串是否以指定字符开头, 类似Java
print(url.endsWith("/")); //当前字符串是否以指定字符结尾, 类似Java
print(url.toUpperCase()); //大写, 类似Java
print(url.toLowerCase()); //小写, 类似Java
print(url.indexOf("scdn")); //获取指定字符的索引位置, 类似Java
print(url.contains("https")); //字符串是否包含指定字符, 类似Java
print(url.trim()); //去除字符串的首尾空格, 类似Java
print(url.length); //获取字符串长度
print(url.replaceFirst("t", "A")); //替换第一次出现t字符位置的字符
print(url.replaceAll("w", "W")); //全部替换, 类似Java
布尔类型–bool
它对应的值只有两个true和false
bool flag = true;
bool isAlive = false;
数字类型–(num、int、double)
在dart中num、int、double都是类,然后int、double都继承num抽象类
注意,但是在dart中没有float, short, long类型
double pi = 3.141592653;
int width = 200;
int height = 300;
print(width / height);//注意:这里和Kotlin、Java都不一样,两个int类型相除是double类型小数,而不是整除后的整数。
print(width ~/ height);//注意: 这才是dart整除正确姿势
print(3.141592653.toStringAsFixed(3)); //3.142 保留有效数字
print(6.6.floor());//6向下取整
print((-6.6).ceil()); //-6 向上取整
print(9.9.ceil()); //10 向上取整
print(666.6.round()); //667 四舍五入
print((-666.6).abs()); // 666.6 取绝对值
print(666.6.toInt()); //666 转化成int,这中toInt、toDouble和Kotlin类似
print(999.isEven); //false 是否是偶数
print(999.isOdd); //true 是否是奇数
print(666.6.toString()); //666.6 转化成字符串
类型检查(is和is!)和强制类型转换(as)
int number = 100;
double distance = 200.5;
num age = 18;
print(number is num);//true
print(distance is! int);//true
print(age as int);//18
集合(List、Set、Map)
集合–List
初始化
var list = [123,234,4,"dsf"];
print(list);
var li = <String>["hello",'welcome',"""dart"""];
print(li);
var list1 = new List();
list1.add(1);
list1.add("hello");
print(list1);
var list2 = new List<String>();
list2.add("Purcell");
list2.add("hello");
print(list2);
print(list1.length);
List遍历:
List<String> colorList = ['red', 'yellow', 'blue', 'green'];//for-i遍历
for(var i = 0; i < colorList.length; i++) {//可以使用var或int
print(colorList[i]);
}
//forEach遍历
colorList.forEach((color) => print(color));//forEach的参数为Function. =>使用了箭头函数
//for-in遍历
for(var color in colorList) {
print(color);
}
//while+iterator迭代器遍历,类似Java中的iteator
while(colorList.iterator.moveNext()) {
print(colorList.iterator.current);
}
集合Set
集合Set和列表List的区别在于 集合中的元素是不能重复 的。所以添加重复的元素时会返回false,表示添加不成功.
var colorSet1 = {'red', 'yellow', 'blue', 'green'};
var colorSet2 = {'black', 'yellow', 'blue', 'green', 'white'};
print(colorSet1.intersection(colorSet2));//交集-->输出: {'yellow', 'blue', 'green'}
print(colorSet1.union(colorSet2));//并集--->输出: {'black', 'red', 'yellow', 'blue', 'green', 'white'}
print(colorSet1.difference(colorSet2));//补集--->输出: {'red'}
集合Map
Map以key-value形式存储,并且 Map对象的中key是不能重复的
Map<String, int> colorMap = {'white': 0xffffffff, 'black':0xff000000};//使用{key:value}形式初始化
var colorMap = <String, int>{'white': 0xffffffff, 'black':0xff000000};
运算符
算术运算符
| 加 | + | var result = 1 + 1; |
| 减 | - | var result = 5 - 1; |
| 乘 | * | var result = 3 * 5; |
| 除 | / | var result = 3 / 5; //0.6 |
| 整除 | ~/ | var result = 3 ~/ 5; //0 |
| 取余 | % | var result = 5 % 3; //2 |
条件运算符
| 大于 | > | 2 > 1 |
| 小于 | < | 1 < 2 |
| 等于 | == | 1 == 1 |
| 不等于 | != | 3 != 4 |
| 大于等于 | >= | 5 >= 4 |
| 小于等于 | <= | 4 <= 5 |
逻辑运算符
| 或 | \|\| | 2 > 1 \|\| 3 < 1 |
| 与 | && | 2 > 1 && 3 < 1 |
| 非 | ! | !(2 > 1) |
位运算符
| 位与 | & |
| 位或 | \| |
| 位非 | ~ |
| 异或 | ^ |
| 左移 | << |
| 右移 | >> |
三目运算符
condition ? expr1 : expr2
var isOpened = (value == 1) ? true : false;
空安全运算符
| result = expr1 ?? expr2 | 若expr1为null, 返回expr2的值,否则返回expr1的值 |
| expr1 ??= expr2 | 若expr1为null, 则把expr2的值赋值给expr1 |
| result = expr1?.value | 若expr1为null, 就返回null,否则就返回expr1.value的值 |
级联操作符(…)
级联操作符是 …, 可以让你对一个对象中字段进行链式调用操作,类似Kotlin中的apply或run标准库函数的使用。
question
..id = '10001'
..stem = '第一题: xxxxxx'
..choices = <String> ['A','B','C','D']
..hint = '听音频做题';
运算符重载
在dart支持运算符自定义重载,使用operator关键字定义重载函数
class Vip {
final int level;
final int score;
const Vip(this.level, this.score);
bool operator >(Vip other) =>
level > other.level || (level == other.level && score > other.score);
bool operator <(Vip other) =>
level < other.level || (level == other.level && score < other.score);
bool operator ==(Vip other) =>
level == other.level &&
score == other.level; //注意: 这段代码可能在高版本的Dart中会报错,在低版本是OK的
//上述代码,在高版本Dart中,Object中已经重载了==,所以需要加上covariant关键字重写这个重载函数。
@override
bool operator ==(covariant Vip other) =>
(level == other.level && score == other.score);
@override
int get hashCode => super.hashCode; //伴随着你还需要重写hashCode,至于什么原因大家应该都知道
}
main() {
var userVip1 = Vip(4, 3500);
var userVip2 = Vip(4, 1200);
if(userVip1 > userVip2) {
print('userVip1 is super vip');
} else if(userVip1 < userVip2) {
print('userVip2 is super vip');
}
}
异常
dart中的异常捕获方法和Java,Kotlin类似,使用的也是try-catch-finally; 对特定异常的捕获使用on关键字. dart中的常见异常有: NoSuchMethodError(当在一个对象上调用一个该对象没有 实现的函数会抛出该错误)、ArgumentError (调用函数的参数不合法会抛出这个错误)
函数
在dart中函数的地位一点都不亚于对象,支持闭包和高阶函数,而且dart中的函数也会比Java要灵活的多,而且Kotlin中的一些函数特性,它也支持甚至比Kotlin支持的更全面。比如支持默认值参数、可选参数、命名参数等
main() {
print('sum is ${sum(2, 5)}');
}
num sum(num a, num b) {
return a + b;
}
在dart函数也是一种类型Function,可以作为函数参数传递,也可以作为返回值。
Function square = (a) {
return a * a;
};
Function square2 = (a) {
return a * a * a;
};
add(3, 4, square, square2)
}
num add(num a, num b, [Function op, Function op2]) {
//函数作为参数传递
return op(a) + op2(b);
add4(num a, num b, {num c, num d}) {
print(a + b + c + d);
}
add5(num a, num b, {num c, num d}) => print(a + b + c + d);
面向对象
在dart中一切皆是对象,所以面向对象在Dart中依然举足轻重,下面就先通过一个简单的例子认识下dart的面向对象,后续会继续深入。
类的基本定义及使用
abstract class Person {
String name;
int age;
double height;
Person(this.name, this.age, this.height);//注意,这里写法可能大家没见过, 这点和Java是不一样,这里实际上是一个dart的语法糖。但是这里不如Kotlin,Kotlin是直接把this.name传值的过程都省了。
//与上述的等价代码,当然这也是Java中必须要写的代码
Person(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
//然而Kotlin很彻底只需要声明属性就行,下面是Kotlin实现代码
abstract class Person(val name: String, val age: Int, val height: Double)
}
class Student extends Person {//和Java一样同时使用extends关键字表示继承
Student(String name, int age, double height, double grade): super(name, age, height);//在 Dart里:类名(变量,变量,...) 是构造函数的写法, :super()表示该构造调用父类,这里构造时传入三个参数
}
类中属性的getter和setter访问器(类似Kotlin)
abstract class Person {
String _name; 相当于kotlin中的var 修饰的变量有setter、getter访问器,在dart中没有访问权限, 默认_下划线开头变量表示私有权限,外部文件无法访问
final int _age;//相当于kotlin中的val 修饰的变量只有getter访问器
Person(this._name, this._age); //这是上述简写形式
//使用set关键字 计算属性 自定义setter访问器
set name(String name) => _name = name;
//使用get关键字 计算属性 自定义getter访问器
bool get isStudent => _age > 18;
}