环境安装
Dart 环境
brew tap dart-lang/dar
brew install dart
开发工具
VS Code + Flutter 插件 + Dash
基础语法
变量
dart 变量是类型推断的,类似 Swift:
var hi = 'Hello World!'; // String
var age = 18; // int
var isMan = tInt; // bool
变量也可以指定类型,但如果指定后则不可以修改类型, var 则可以动态变更:
String hi = 'Hello World!';
int age = 18;
bool isMan = true;
变量属性 var 、final 、const:
var hi = 'Hello World!'; // 可变
final age = 18; // 赋值后不可变
const isMan = true; // 编译期间赋值,并不可变
类型
dart 支持以下类型:
- numbers (int, double)
- strings (String)
- booleans (bool)
- lists (List)
- sets (Set)
- maps (Map)
- runes (UTF-32 字符串)
- enum (集合)
操作符
参考 Swift、C,几乎都一样。
函数
类似 C 语言的函数定义:
int addition(int a, int b) {
return a + b;
}
addition(1, 3); // 4
dart 的函数可以动态推荐返回类型,同时也可以写成:
addition(int a, int b) {
return a + b;
}
dart 函数指定参数名称:
addition({int a, int b}) {
return a + b;
}
print(addition(a: 1, b: 3));
只有一行实现代码时可以使用箭头函数:
addition({int a, int b}) => a + b;
print(addition(a: 1, b: 3));
匿名函数:
var sayHi = () => print("Hi Dart!");
sayHi();
var sayHello = ({String name}) => print("Hello," + name);
sayHello(name: "Dart");
分支 & 循环
if else if else…..
final num = 89;
if (num >= 85) {
print('优秀');
} else {
print("一样优秀");
}
switch case
switch (num) {
case 84:
print(0);
break;
case 85:
case 86:
print(100);
break;
default:
print(0);
}
三目运算:
var a = 100;
var b = 200;
a < b ? a = b : b = a;
for 循环:
for (var i = 0; i < 100; i++) {
print(i);
}
for (var item in [1, 2, 3, 4, 5]) {
print(item);
}
while:
var num = 1;
while (num < 100) {
num++;
}
do {
num++;
} while (num < 200);
类
创建类,参考 C++:
class UserInfo {
int age;
String name;
UserInfo(int age, String name) {
this.age = age;
this.name = name;
}
}
main(List args) {
final user = UserInfo(18, "帅气");
print(user.name);
}
更友好的构造方法:
class UserInfo {
int age;
String name;
// UserInfo(int age, String name) {
// this.age = age;
// this.name = name;
// }
// equal to
UserInfo(this.age, this.name);
}
默认构造函数:
class UserInfo {
int age;
String name;
UserInfo({int age = 18, String name = "人穷样衰"}) {
this.age = age;
this.name = name;
}
}
main(List args) {
final user = UserInfo();
print(user.name);
}
命名构造函数:
class UserInfo {
int age;
String name;
String id;
UserInfo({int age = 18, String name = "人穷样衰"}) {
this.age = age;
this.name = name;
}
UserInfo.otherInit(int age, String id) {
this.age = age;
this.id = id;
}
}
main(List args) {
final user = UserInfo.otherInit(18, "120202021020");
print(user.name); // null
print(user.id); // 120202021020
}
类的浅拷贝:
final user = UserInfo.otherInit(18, "120202021020");
var u1 = user;
print(u1.age); // 18
user.age = 20;
print(u1.age); // 20
类没有默认的深拷贝行为,但可以给类加一个拷贝方法实现深拷贝功能:
UserInfo copy () => UserInfo(xxx, xxx, xxx)
类属性 & 类方法:
class Person {
static const canWalk = true;
static walk(){
}
}
注意:dart 运行时垃圾回收,不需要手动回收垃圾。
面向对象
派生
从基类派生,通过 extend 关键字实现的:
class Person {
String name;
Person(this.name);
myName() {
print("My name is " + this.name);
}
}
class Student extends Person {
String sId;
Student(String name, String sId) : super(name) {
this.sId =sId;
}
}
main(List args) {
var s = Student("Me", "120202021020");
s.myName();
}
多态
类的函数可以通过 @override 对方法进行重写:
class Person {
String name;
Person(this.name);
myName() {
print("My name is " + this.name);
}
}
class Student extends Person {
String sId;
Student(String name, String sId) : super(name) {
this.sId =sId;
}
@override
myName() {
print("I'm a student, my name is " + name);
}
}
main(List args) {
var s = Student("Me", "120202021020");
s.myName();
}
抽象类 & 抽象方法
抽象类与抽象方法,相当于 OC、Swift 的 protocol,只是定义一个类和方法,并没有具体的实现。我们可以通过abstract 来实现抽象类:
abstract class RequestAPI {
String url;
request();
}
然后通过 implements 来实现抽象类:
class UserInfoRequest implements RequestAPI {
String url;
UserInfoRequest(this.url);
request() {
print("request user info");
}
}
main(List args) {
var request = UserInfoRequest("https://yxxxhao.com/user/userinfo");
request.request();
}
mixin
不知道该怎么形容,感觉你有点像 Swift 的扩展,实现的代码可以在任意地方使用它:
mixin AlertOperation {
show(String msg) => print(msg);
dismiss() => print('dismiss alert view');
}
class UserInfoRequest with AlertOperation implements RequestAPI {
String url;
UserInfoRequest(this.url);
request() {
show("request user info");
}
}
异步
dart 中使用到异步操作时, 需要先引入异步操作的核心库:
import 'dart:async';
Future
Future 是什么?如果你对 Promise 有所了解,Future 也是同样的意思,简单点理解:"如果特定的操作完成了,那么执行特定的代码"。
class UserInfoRequest {
String url;
UserInfoRequest(this.url);
Future> getFriendList(String uid) {
return new Future>(() {
// api request
return [
'friend1',
'friend2',
'friend3'
];
});
}
}
main(List args) {
var request = UserInfoRequest("https://yxxxhao.com/userinfo");
request.getFriendList("1202").then((list) => {
print(list)
}).catchError((error) => {
print(error)
});
}
Async & Await
我们可能通过 Async & Await 对 Future 代码进一优化,我们可以用 async 来标识 main 方法里面存在异步操作,然后通过 await 来等待异步操作回来,通过 catch 来捕获异常,达到用写同步代码的方式来实现异步操作:
main(List args) async {
var request = UserInfoRequest("https://yxxxhao.com/userinfo");
try {
var list = await request.getFriendList("1202");
print(list);
}
catch (error) {
print(error);
}
}
实践
LeetCode 题目练习
-
500. 键盘行
findWords(List
words) { var list = []; var keys = ["qwertyuiop", "asdfghjkl", "zxcvbnm"]; for (String word in words) { final array = word.toLowerCase().runes.toList(); for (var str in keys) { var arr = str.runes.toList(); for (var i = 0; i < array.length; i++) { if (!arr.contains(array[i])) { break; } if (i == array.length - 1) { list.add(word); } } } } return list; } print(findWords(["Hello", "Alaska", "Dad", "Peace"])); -
349. 两个数组的交集
List
intersection(List nums1, List nums2) { Set s = {}; List list = []; for (var num in nums1) { if (!s.contains(num)) { s.add(num); } } for (var num in s) { if (nums2.contains(num)) { list.add(num); } } return list; }
网络请求
-
请求用户信息
getUserInfo() async { var httpClient = new HttpClient(); var uri = new Uri.http('yxxxhao.com', '/user/userinfo', {'uid': '120202'}); try { var request = await httpClient.getUrl(uri); var response = await request.close(); print(response); } catch (error) { print(error); } } main(List
args) async { getUserInfo(); }