三. Dart语法学习2

  1. Dart基本类型常用Api介绍
  • 布尔类型

Dart中布尔类型很简单。如C语言中用bool声明,对应true & false

  • 数字类型

int double 都继承num抽象类,他两也是抽象类

//抽象类 num定义
abstract class num implements Comparable<num> {
}
  • 字符类型String

字面量表示两种方法:

  1. 单行使用单引号或者双引号包裹
  2. 多行使用三个单引号或者三个双引号包裹
  String textA = '字符串A';
  String textB = "字符串A";
  String textC = '''
                 字符串C,
                 字符串C,
                 字符串C,
                 字符串C,
                 ''';

  String textD = """
                 字符串D,
                 字符串D
                 """;

字符串常用Api:

//获取字符长度
  var length = text.length;
  //方法删除所有前导和尾随空格返回一个新字符串。 但是,此方法不会丢弃两个字符串之间的空格。
  var text1 = text.trim();
  print(text1); //'我热爱编程,喜欢D a r t'

  var text2 = text.trimRight();
  print(text2); //'  我热爱编程,喜欢D a r t'

  var text3 = text.trimLeft();
  print(text3); //'我热爱编程,喜欢D a r t '

  //判断是否包含某个字符串;两个参数1.包含的字符串,2从字符第几位开始查找包含,有默认参数startIndex =0
  bool contained1 = text.contains('D a r t');
  print(contained1); //true
  bool contained2 = text.contains('D a r t', 14);
  print(contained2); //false

  //查找字符串在text字符中的起始索引,返回-1未找到;有默认参数startIndex =0
  int index = text.indexOf("编程");
  print(index); //5

  //字符以某个字符串结尾,类型OC hasSuffix
  bool isEnd = text.endsWith(' ');
  print(isEnd); //true

  //字符以某个字符串结尾,类型OC hasPrefix;有默认参数startIndex =0
  bool isStart = text.startsWith('我', 2);
  print(isStart); //true

  //字符串替换 from - 要被替换的字符串。replace - 替换字符串
  String text4 = text.replaceAll(' ', '*');
  print(text4); //**我热爱编程,喜欢D*a*r*t*

  //字符串分割,类似oc的componentsSeparatedByString
  List<String> strList = text.split(' ');
  print(strList); //[, , 我热爱编程,喜欢D, a, r, t, ]
 
  //字符串字母大小写转换
  var test = "Dart";
  var test1 = test.toLowerCase();
  print(test1);//dart
  var test2 = test.toUpperCase();
  print(test2);//DART
  • 数组类型List
List声明:
  List list = List(3);
  List list1 = [1, 2, 3];

  print(list);//[null, null, null]
  print(list1);//[1, 2, 3]

List常用属性和函数

 var text = '  我热爱编程,喜欢D a r t ';
  List list = [2, 4, 8, 16, 32, 64, 'Dart'];
  //length 数组长度,set get 都可,这里要注意
  int length = list.length;
  print(length); //6
  print(list); //[2, 4, 8, 16, 32, 64]
  list.length = 10;
  print(list); //[2, 4, 8, 16, 32, 64, null, null, null, null]

  //数组是否为空,很简单
  bool result = list.isEmpty;
  print(result); //false

  //数组是否包含某个元素
  bool isContained = list.contains('Dart');
  print(isContained); //true

  //数组遍历
  list.forEach((element) {
    print(element);
  });

  //依次访问数组元素,根据指定函数计算一个结果
  int total = list.reduce((value, element) {
    if (value is num == false) {
      value = 0;
    }

    if (element is num == false) {
      element = 0;
    }

    return value + element;
  });
  print(total); //126

  //数组转换成字符串
  var joinStr = list.join("*");
  print(joinStr); //2*4*8*16*32*64*Dart*null*null*null

  //增
  list.add(100);
  print(list); //[2, 4, 8, 16, 32, 64, Dart, null, null, null, 100]
  //删
  list.removeAt(1);
  print(list); //[2,8, 16, 32, 64, Dart, null, null, null, 100]
  //将数组全部追加进数组
  list.addAll([001, 002, 004]);
  print(list); //[2, 8, 16, 32, 64, Dart, null, null, null, 100, 1, 2, 4]
  //修改
  list.fillRange(1, 2, 200);
  print(list);
  //insert(index,value); 指定位置插入

  //insertAll(index,list) 指定位置插入List

  //toList() 其他类型转换成List
 //清空
  list.clear();
  print(list);//[]
  • Map类型
Map声明
  var map = {};
  Map map1 = Map();

常用Api跟数组差不多,简单介绍一下:

 var map = {};
  Map map1 = Map();
  //插入键值对
  map["name"] = "Dart";
  print(map);

  bool re1 = map.containsKey("name");
  bool re2 = map.containsValue("Dart");
  print(re1);
  print(re2);

  //跟OC 类似,注意map取entries
  map.addEntries({"age": "18", "gender": "男"}.entries);
  print(map);

  //将Map全部添加进来,注意addEntries区别
  map.addAll({"age": "22"});
  print(map);

  //遍历
  map.forEach((key, value) {});
  //删除
  map.remove("name");

  //清空
  map.clear();

  //length获取长度,注意read only,跟数组区别
  int length = map.length;
  print(length);

  //判空
  map.isEmpty;
  1. 函数

在dart中函数的也是对象,支持闭包和高阶函数,而且dart中的函数也会比OC要灵活的多,比如支持默认值参数、可选参数、命名参数等

  • 函数基本用法
void main() {
  print(getInfo("小明", 18, "未知"));
}

String getInfo(String name, int age, String gender) {
  return name + age.toString() + '岁了性别' + gender;
}
  • 函数参数传参

函数参数构成图:
Dart函数.png
  1. 位置参数
//1.无返回值 无参数函数
printInfo() {
  print("我是 无参数 无返回值 函数");
}

//2. 无参数有返回值函数
String getInfo() {
  return "无信息";
}

//3.有参数且参数个数,顺序固定(均为必需参数)
String getInfo1(String name, int age, String gender) {
  return name + age.toString() + '岁了性别' + gender;
}

//4.dart 中声明可选参数,需要在参数列表声明 List 格式的参数列表,表明是可选的。并且List格式参数列表需要在必需参数列表后边,多个可选参数也是按照顺序的
String getPersonInfo(String name, int age, String gender, [String address]) {
  if (address == null) {
    return name + age.toString() + gender;
  }

  return name + age.toString() + gender + address;
}

//5.位置参数,可选参数带默认值函数(必需放在可选参数列表中[])
String getPersonInfo1(String name, int age, String gender,
    [String address = 'Google']) {
  return name + age.toString() + gender + address;
}
  1. 命名参数(命名参数始终是可选参数,可以设置默认值)
//1.  命名参数(参数列表中由map 构成{},其位置在必须放在位置参数后)
//使用resutl1 = sum1(b: 2, c: 3);
int sum({int a, int b, int c}) {
  return a + b + c;
}

//2. 命名参数 含默认值参数
//使用resutl2 = sum1(b: 2, c: 3););
int sum1({int a = 10, int b, int c}) {
  return a + b + c;
}

//2. 命名参数 含默认值参数,必需位置参数(@required 修饰,只有在命名参数中可以使用)
//使用 int result2 = sum2(b: 10);
int sum2({int a = 10, @required int b, int c}) {
  return a + b + c;
}

//3.位置参数,命名参数 混合使用(注意 位置参数只能使用必需位置参数)
//使用 int result3 = sum3(1, c: 3);
int sum3(int a,{int b,@required int c,int d = 100}) {
  return a + b + c + d;
}

//4.错误使用报错,命名参数 混合
//不可使用
// int sum4([int a], {int b,@required int c,int d = 100}) {
//   return a + b + c + d;
// }
  1. 箭头函数(箭头函数只能有一行,可以省略大括号.只是省略写法)
int sum5(int a, int b) => a + b;

4.匿名函数(没有名字的函数)

//带参数的匿名函数
(a,b){

  }
//匿名方法赋值给一个变量,然后可以使用这个方法
var sum = (a,b){
    return a + b;
  }

//定义参数带函数的函数
test(int a, int b, add(c, d)) {
  return add(a, b);
}

int blockTest(List<int> list, block(int a, int b)) {
  int value = 1;
  for (int item in list) {
    value = block(item, value);
  }
  return value;
}
//调用:
void main() {
  int value = add(100, 200);
  print(value.toString());
  //将add函数当成变量传进函数
  test(100, 200,add);//输出300;

//函数当做参数传参
 int value = blockTest([1, 2, 3, 4, 5], (a, b) {
    return a * b;
  });
  print(value);//value 120;
}
  1. 闭包 (即一个函数对象,即使函数对象的调用在它原始作用域之外,依然能够访问在它词法作用域内的变量,能够捕捉变量);
  • 闭包在函数体内部实现
blockTest01(int a) {
  int value = 0;
  test() {
    value++;
   //捕获外部变量value
    print((a + value).toString());
  }

  return test;
}

//调用:
void main() {
var block01 = blockTest01(100000);
//blockTest01 函数体内局部变量 value 在函数执行完成后 不会被释放,多执行几次 可以发现
  block01();//100001
  block01();//100002
  block01();//100003
}
  • 闭包在函数体外部实现(函数当做参数传递,类似iOS block)
int blockTest(List<int> list, block(int a, int b)) {
  int value = 1;
  for (int item in list) {
    value = block(item, value);
  }
  return value;
}

//调用:
void main() {
  int value = blockTest([1, 2, 3, 4, 5], (a, b) {
    return a * b;
  });//120
}

闭包在Flutter 使用很多 比如常见的builder 模式 就是使用闭包 ,返回我们自定义的组件

  ListView.builder({
    Key key,
    Axis scrollDirection = Axis.vertical,
    bool reverse = false,
    ScrollController controller,
    bool primary,
    ScrollPhysics physics,
    bool shrinkWrap = false,
    EdgeInsetsGeometry padding,
    this.itemExtent,
    @required IndexedWidgetBuilder itemBuilder,
    int itemCount,
    bool addAutomaticKeepAlives = true,
    bool addRepaintBoundaries = true,
    bool addSemanticIndexes = true,
    double cacheExtent,
    int semanticChildCount,
    DragStartBehavior dragStartBehavior = DragStartBehavior.start,
  }) 

我们看一下IndexedWidgetBuilder定义typedef IndexedWidgetBuilder = Widget Function(BuildContext context, int index);原来是一个返回值为Widget类型的函数,我们在调用的时候 在闭包中 根据需要返回不同的自定义的widet即可;

ListView.builder(itemBuilder: (BuildContext context, int inx) {
    return Text('闭包');
  });

我们可以思考一下 这种做法的好处?
还记得List的 reduce函数 也是闭包的用法,我们可以根据我们自己定义的算法获取相应的结果,配合泛型等使用,使我们的代码很优雅,复用性也很高.

[].reduce((value, element) {
    return value * element;
  });

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