Dart 学习

变量
  • var 关键词
    使用var 声明的变量,默认是dynamic 【类似于泛型】
var varA;  
//赋值为整型 
varA = 10; 
//注意,改变变量类型是不可接受的,可以理解为swift中的类型推断,也就是所说的类型安全。
varA = "ten";
Error: A value of type 'int' can't be assigned to a variable of type 'String'.

我也很好奇的尝试了一下 let

let year = "2019";  

Error: A value of type 'String' can't be assigned to a variable of type 'invalid-type'.
//显然,Dart 并没有这个关键词用于限定不可变类型,不过有其它的。

Dart是面向对象的语言,其中所有对象和类型都继承于Object基类
注意 ObjectO是大写的!!!

  • dynamic关键词
dynamic valueT = "string value";
//可以放心的指向任意类型了
valueT = 100;
  • Object 声明的对象 、同样能声明一个泛型
Object objA = "string value";
objA = 100;

区别
dynamic声明的变量可以调用可能的方法,但是别想多了这个只能让你安全度过编译期,在运行期还是会检查函数签名的。
类似于

dynamic  varA = "time";
varA.length; 

varA.someFunction;
Error:  get$someFunction is not a function.

varA.someFunction();
Error: someFunction$0 is not a function
 //someFunction  Dart的排异反应还是有的

Object 声明的变量,只能调用基类才有的方法

Object objA = "string value";
objA.length; //这里的效果可能就是,屏蔽了类型推断机制。
  • 静态变量

const 关键词 【注意 可以不声明类型】

//编译时常量
const String valueA = "hi";
const valueB = "const";

final 关键词 【可不用声明类型】

//仅能被初始化一次,使用时初始化。
final String valueA = "hi";
final valueB = "final";

思考 如果进行类型转换 【类型转换实验】

var varA = 100;
//基于以往习惯 【错误】
String varB = String(varA);
//as  【错误】
String varC = varA as String;
//老老实实的 使用对象方法吧
String varD =  varA.toString();

函数

Dart 中函数既可以作为参数,也可以作为一个类型,函数式编程的身影~~~

  • 无返回值函数
void noReturnFunction(){
  print("无返回值的函数");
}
void noReturnWithParamFunction(int value) {
  print(value);
  print("无返回值,但有参数的函数");
}
  • 有返回值的函数
bool isEqual(int a, int b){
  return a==b;
}

//未显示声明返回值类型,返回值 是被标记为 dynamic的。
isEqual_A(int a, int b){
  return a==b;
}

插播一条,关于【函数简写】 如果函数体仅有一条语句

bool isEqual(int a, int b){
  return a==b;
}

==》省略 {}

 bool isEqual(int a, int b) => return a==b;

==》省略 返回值类型

 isEqual(int a, int b) => return a== b;

==》省略 return

 isEqual(int a, int b) => a==b;

==》别想了,这是不可能的...

 isEqual => a==b; 

插播第二条,关于【函数重载】

int isEqual(String strA, String strB) {
  return strA.compareTo(strB);
}

bool isEqual(int a, int b){
  return a==b;
}

Error: 编译器会告诉你,这个真的实现不了~~~
  • 函数作为变量
var varF = (strValue) {
  print("get   $strValue ");
}

varF("Time");
  • 使用typedef声明函数类型
typedef void noReturnFunction(String);
typedef String returnStringFunction(String);
...
  • 函数作为参数传递 【想想var 和 dynamic 的联系和区别】
var varF = () {
  print("hello");
}

void printFunction(var func){
  func();
}

//调用
printFunction(varF);
  • 函数【可选参数】
//想起了 OC 的 ...  
void mutableParamsFunction(String a, ...){
  读取参数列表 balabala...
   ...
}
Error: 别想了,也没戏

//这里 [] 用于表示可选参数
void optionFunction(String a, String b, [String c]) {
  ...
  //使用可选参数时,需要判断
 if(c != null) {
  ...balabala 
  }
}

//调用
optionFunction("hi","flutter");
optionFunction("hi","flutter","option");
  • 函数【可选参数命名】
void optionParamsNameFunction({String strA, String strB}) {
  ...balabala
}

//实际效果 在调用的时候就能看出来了
optionParamsNameFunction(strA: "hi", strB: "flutter");
【注意】 一个有趣的尝试
optionParamsNameFunction(strB:"flutter", strA:"hi");

异步编程

Future 【感受 类似GCD 和 链式编程思想的结合体】

  • 延时
//延时5秒
Future.delayed(new Duration(seconds:5),() {
  ...
}).then((anyThing){
  ...
});

Future中几乎所有可用的方法,均会返回Future本身,为实现链式调用创造了基础。

  • 异常抛出及其捕获
> 1 

Future.delayed(new Duration(seconds:2),(){
  ...
  throw AssertionError("Error desc...");
}).then((anyThing){
  //注意 一旦发生异常,此处代码不会被执行
}).catchError((e){
  //捕获异常
  print(e.message);
});

> 2 then 可选参数捕获异常
Future.delayed(new Duration(seconds:2),(){
  throw AssertionError("Error desc...");
}).then((anyThing){
   ...
},onError:(e){
   //可选参数 中捕获到异常
   print(e.message);
});

> 3 无论是或否发生异常,最终均会执行的需求实现

Future.delayed(new Duration(seconds:2),(){
  throw AssertionError("Error desc...");
}).then((anyThing){
  ...
}).catchError((e){
  print(e.message);
}).whenComplete((){
  ...
  print("do anything u want...");
});
  • 异步事件同步 【相当于 GCD栅栏】
 Future.wait([
   //事件一
    Future.delayed(new Duration(seconds:2),(){
      return "wait";
    }),
    //事件二
    Future.delayed(new Duration(seconds:4),(){
      return " me please";
    })
    
  ]).then((results){
   //results 相当于整合了异步事件的所有结果到一个数组中
    print(results[0] + results[1]);
  }).catchError((e){
    print(e);
  });

  • Future 函数改造

个人理解:可以将任意函数 返回值处理成Future对象
这一点尤其像RAC中的信号概念

//一个模拟获取用户名的函数
> 1 照葫芦画瓢
Future<String> getUserName() {
  return "tom"
}

结果是编译器报错,大概意思就是 返回值 int 与 Future<String>类型冲突,
之后也尝试查找了有没有方法可以把任意类型包装成Future对象,但没有找到。

> 2 领悟到一点儿
Future<String> getUserName() async {
  return "Saylor";
}
对一个函数 使用 async 关键词表明其运行在异步模式中时,
Dart编译器会自动将返回值进行Future对象封装。

【运行尝试】
getUserName().then((strName){
  print(strName);
}).whenComplete((){
  print("complete...");
});
  • 回调地狱 Callback hell 【实际指的就是 block嵌套使用的情况】
现有的编程经历中,的确很多时候热衷于使用闭包,
但是积累到一定程度的时候往往会发现闭包使用过程中不可避免会出现嵌套。

[obj loginUserName:strName pwd:strPwd  Result:^(str strUserId){
       ...     
      [obj  getUserInfoWithUserId:strUserId Result:^(UserInfo * userInfo){
       ...
      }];
}];

使用future 改善的原理其实就是,返回值是被封装的Future对象,进而能够形成链式调用。(个人缪解)
Future<String> login(String strName, String pwd) async {
    ... 网络请求 balabala...
    strUserId = ...
    return strUserId;
}

Future getUserInfo(String strUserId) async {
       ... 网络请求 balabala...
    userInfo = ...
    return userInfo;
}

//调用
login("saylor","pwd").then((strUserId){
    return getUserInfo(strUserId);
}).then((userInfo){
   //...
});

  • await 异步变同步
【注意】  该关键词会阻塞当前线程,故必须运行在异步线程中!!!
//声明一个异步方法
task() async {
 try{
    String strUserId = await login("tom","***");
    UserInfo userInfo = await getUserInfo(strUserId);
    ...
  }catch(error){
    print(error.message);
  }
}

这种最显著的效果:以同步工作流的方式,去完成异步任务。
更符合猿类平时的编程习惯~~~
Stream 【流... 可以理解为 任务队列】

同Future 一样,主要应用于异步编程中。不同之处,在于Stream 可以将多个Future 任务组装成工作流,并监听各个任务的完成情况。

String.fromFutures([
      Future.delayed(new Duration(seconds:1),(){
        //task 1
        ...
         return "res_1";
    }),

      Future.delayed(new Duration(seconds:1),(){
        //task 2
        ...
         return "res_2";
    }),
    ... 可以自行累加
    
]).listen((res){
  //这里 res , 不同于 Future.wait 中所做的处理,每一个任务完成均能够监听到。(多次执行)
    ... 
}.onError:(error){
  //捕获异常
  print(error.message);
},onDone:(){
  //工作流任务完成【全部完成】

});

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容

  • Flutter日渐火爆,因此在进行Flutter学习前先学习一些其所使用的开发语言dart的基础,这篇文章主要学习...
    Samlss阅读 10,838评论 2 28
  • 一个基本的Dart程序 下面的代码中使用了很多Dart最基本的特性: 重要概念 所有你能够赋值给一个变量的都是一个...
    YZune阅读 14,498评论 2 14
  • Dart的设计目标应该是既对标Java,也对标JavaScript,Dart在静态语法方面和Java非常相似,如类...
    寒桥阅读 6,926评论 3 11
  • dart是一种面向对象的语言,具有类和基于mixin的继承。每个对象都是一个类的实例,所有的类都是 的子类。基于m...
    你需要一台永动机阅读 1,602评论 0 4
  • Dart库充满了返回Future或Stream对象的函数。这些函数是异步的:它们在设置一个可能耗时的操作(如I /...
    你需要一台永动机阅读 2,113评论 0 0