Dart初识:数据类型、运算符、条件表达式等

Dart介绍:

Dart是由谷歌开发的计算机编程语言,它可以被用于web、服务器、移动应用 和物联网等领域的开发。
Dart诞生于2011年,号称要取代JavaScript。但是过去的几年中一直不温不火。直到Flutter的出现现在被人们重新重视。

要学Flutter的话我们必须首先得会Dart。

官网:https://dart.dev/

Dart环境搭建:

要在我们本地开发Dart程序的话首先需要安装Dart Sdk
官方文档:https://dart.dev/get-dart

  windows(推荐):
  http://www.gekorm.com/dart-windows/

  mac:
  如果mac电脑没有安装brew这个工具首先第一步需要安装它:  https://brew.sh/
  brew tap dart-lang/dart
  brew install dart

Dart 开发工具:

  Dart的开发工具有很多: IntelliJ IDEA  、 WebStorm、 Atom、Vscode等

语法:入口、注释、变量、常量命名规则

入口方法的两种定义方式:

main(){
    print('你好dart');
  }
void main(){
 print('你好dart');
}

void 代表无返回值,有点像java程序的入口

注释有

/*
注释
*/

/// 或者 //

Dart 变量:dart是一个强大的脚本类语言,可以不预先定义变量类型 ,自动会类型推倒
dart中定义变量可以通过var关键字可以通过类型来申明变量
如:

var str='this is var';
String str='this is var';
int str=123;

注意: var 后就不要写类型 , 写了类型 不要var 两者都写 var a int = 5; 报错

Dart 常量: final 和 const修饰符
const值不变 一开始就得赋值
final 可以开始不赋值 只能赋一次 ; 而final不仅有const的编译时常量的特性,最重要的它是运行时常量,并且final是惰性初始化,即在运行时第一次使用前才初始化
永远不改量的量,请使用final或const修饰它,而不是使用var或其他变量类型。

final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';

const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere

Dart的命名规则:

1、变量名称必须由数字、字母、下划线和美元符($)组成。
2.注意:标识符开头不能是数字
3.标识符不能是保留字和关键字。   
4.变量的名字是区分大小写的如: age和Age是不同的变量。在实际的运用中,也建议,不要用一个单词大小写区分两个变量。
5、标识符(变量名称)一定要见名思意 :变量名称建议用名词,方法名称建议用动词 

Dart的数据类型

与java对比,Dart没有那么丰富的数据类型
常用的数据类型有:
1、数值类型:int、double (没有flout、short等)
2、字符类型:String(没有char类型)
3、布尔类型:bool(和java中的boolean区别,bool只接收true/false,不能像java中的布尔类型一样接受0和其他整型)
4、List(数组/集合)在Dart中,数组是列表对象,所以大多数人只是称它们为列表
5、Maps(字典)通常来说,Map 是一个键值对相关的对象。 键和值可以是任何类型的对象。每个键只出现一次, 而一个值则可以出现多次

1、数值类型

  /***
   * int 测试
   */
  var i1 = 123;
  //i1 = 123.00;//会报错,i1被自动定义成了int类型,再给它赋值double类型是不行的
  print(i1);

  var i2 = 123.00;
  i2 = 111;//i2被自动定义成double类型,后赋值111时,i2还是double类型,所以打印出来的数值是111.0
  print(i2);

2、字符类型

/**
   * 字符串测试
   */
  String str1 = "this is str1";
  String str2 ='this is str2';
//三个单引号或三个双引号括起来的字符串,会保持原有样式换行输出,这个是同单个双引号或单引号相比的区别
  String str3 ='''this is str3
  this is str3
  this is str3
  ''';
  
  String str4=""" this is str4   this is str4
  this is str4
  """;
  print(str1);
  print(str2);
  print(str3);
  print(str4);

3、布尔类型bool

/**
   * 布尔类型测试
   */
  bool f1 = true;
  bool f2 = false;
  // f1 = 0;//报错,bool类型不能被int赋值
  // f2 = 123;//报错,bool类型不能被int赋值
  if(f1 is String){
    print("f1 is String");
  }else if(f1 is bool){
    print("f1 is bool");
  }else{
    print("is other");
  }

4、List集合(列表/数组)

/**
   * List数组/列表测试
   */
  var a = ["aaa", "bbb", 110];
  List b = [];
  // List c = new List();//这种声明方式是错误的,声明一样新的空列表,要使用List c = []
  b.add("aaa");
  b.add("bbb");
  b.add(110);
  print(a);
  print(b);

5、Map字典

/**
   * Map字典测试
   */
  //直接赋值,采用json的格式,取其中具体key的值时用map["xxx"]方式
  Map map = {
    "name": "jack",
    "age": 12,
    "work": ["安卓开发", "java后台", "架构师"]
  };
  print(map);
  print(map["name"]);
  //第二种定义方式,同第一种直接赋值方式得到的结果相同
  var map1 = new Map();
  map1["name"] = "xuqingsong";
  map1["age"] = 31;
  map1["work"] = ["安卓开发", "java后台", "架构师"];

  print(map1);

Dart判断数据类型:is 关键词来判断类型

Dart运算符

算术运算符

+    -    *    /     ~/ (取整)     %(取余)

测试代码如下:

  /**
   * 运算符测试
   */
  int a = 13;
  int b = 5;
  print(a+b);//加
  print(a-b);//减
  print(a*b);//乘
  print(a/b);//除
  print(a~/b);//取整
  print(a%b);//取余

结果值:
18
8
65
2.6
2
3

值得注意的时,这里除数和被除数都是int类型,但是除法得到的结果值是小数,不会像java一样结果值类型由除数或被除数限定为int类型

关系运算符

==    !=   >    <    >=    <=

关系运算符用在条件判断里,同其他语言是一样的,这里就不进行代码示范了。

逻辑运算符

 !            &&         ||

取反          并且          或者

逻辑运算符的意义同其他语音如java一致,这里不再赘述

赋值运算符

基础赋值运算符   =   ??=
复合赋值运算符   +=  -=  *=   /=   %=  ~/=

复合赋值运算符同java中一致(+= 、 -=、 *= 、 /= 、 %= 、 ~/=,==),其中??=代表的意思是,当值为空时,复制等号后面的值。如:

/**
   * 赋值运算
   *
   */
  var a;
  var b = a ??= "10";
  print("b = " + b);

结果是
b = 10



 var c = "12";
 var d = c ??= "20";
 print("d = " + d);

结果是

main.dart:99:11: Warning: Operand of null-aware operation '??=' has type 'String' which excludes null.
  var d = c ??= "20";
          ^
d = 12

感觉这个赋值运算有问题,居然报出警告,但是又给到了正确值,注意这里的变量类型必须是可空的字符串,
int类型是会报错的。
看visual studio演示是int是可以的

条件表达式

if  else   switch case 

这里要说明一下的是,switch同java8相似,case支持是字符串类型。

/**
   * if else switch case 演示
   */
  var a = "男";
  var b = "女";
  
  if(a == "男"){
    print("a 是 男");
  }else{
    print("a 不是 男");
  }

  var c;
  switch(b){
    case "男":
      print("switch is 男");
      break;

    case "女":
      print("switch is 女");
      break;

    default:
      print("switch is default");
      break;
  }
  switch(c){
    case "男":
      print("switch is 男");
      break;

    case "女":
      print("switch is 女");
      break;

    default:
      print("switch is default");
      break;
  }


结果值:

a 是 男
switch is 女
switch is default

三目运算符

表达式 ? 为true时的赋值 :为false时的赋值

示例如下:

/**
   * 三目运算符测试 ?? xxx:yyy
   */
 String a ="";
 print("a =" + a);
 String b = a == "" ? 'xxx' : 'yyy';
 print(b);

结果是
a =
xxx

a首先赋值为空字符串,所以打印出来是空字符串,然后判断为true时赋值为“xxx”

类型转换

 /**
   * Sting类型和int类型互转:
   * int 转 String 用toString
   * String 转 int 用parse
   */
  String a = "123";
  int b = int.parse(a);
  print(b);
  print(b is int);

  int c = 110;
  print(c.toString());

结果值:

123
true
110

类型转换时,数值转换建议用double代替int,这样可以规避很多问题。
其次String转成具体数值如double类型时,注意字符串为空的时候的异常问题

/**
   * Sting类型和int类型互转:
   * int 转 String 用toString
   * String 转 int 用parse
   */
  String c = "";
  try {
    double d = double.parse(c);
    print(d);
  } catch (err) {
    print(err);
  }

结果值:
FormatException: Invalid double

记得try/catch

其他类型转为bool类型

/**
   * 其他类型转换成bool类型,主要是依靠==来组成判断表达式
   */
  var a;
  if(a == null){//此处a类型无法推导出,不能用a.isEmpty方法。NoSuchMethodError: The getter 'isEmpty' was called on null.
    print("a 空");
  }else{
    print("非空");
  }

  String b = "";//此处b被使用,必须赋值,只声明不赋值会报错
  if(b.isEmpty){
    print("b isEmpty");
  }else{
    print("非 isEmpty");
  }

  int c = 0;//此处的c在使用时必须赋值,只声明不赋值会报错
  if(c == 0){
    print("c == 0");
  }else{
    print("c 非 0");
  }

特殊值NaN


  /**
   * 特殊值NaN,使用方法isNaN进行判断
   */
  var a = 0/0;//0不能作为除数,此时并不会抛异常,a会被赋值成NaN
  if(a.isNaN){
    print("a isNaN");
  }else{
    print("a != NaN");
  }

结果是:

a isNaN

自加自减:++ --

 /*
     ++  --   表示自增 自减 1
    在赋值运算里面 如果++ -- 写在前面 这时候先运算 再赋值,如果++ --写在后面 先赋值后运行运算
  */
 var a=10;
 var b=a--;

 print(a);  //9
 print(b);  //10

var a=10;
 var b=--a;

 print(a);  //9
 print(b);  //9

for循环

/*

// for基本语法
            //第一步,声明变量int i = 1;
            //第二步,判断i <=100
            //第三步,print(i);
            //第四步,i++
            //第五步 从第二步再来,直到判断为false
*/
 for (int i = 1; i<=10; i++) {   
            print(i);
          }

结果值:只打印打1到10

while/do while

while(表达式/循环条件){            
            
        }

do{
    语句/循环体
            
}while(表达式/循环条件);
        
                
注意: 1、最后的分号不要忘记
2、循环条件中使用的变量需要经过初始化
3、循环体中,应有结束循环的条件,否则会造成死循环。

break和continue的区别

break语句功能:
1、在switch语句中使流程跳出switch结构。
2、在循环语句中使流程跳出当前循环,遇到break 循环终止,后面代码也不会执行
          
强调:
1、如果在循环中已经执行了break语句,就不会执行循环体中位于break后的语句。
2、在多层循环中,一个break语句只能向外跳出一层

break可以用在switch case中 也可以用在 for 循环和 while循环中

continue语句的功能:
              
【注】只能在循环语句中使用,使本次循环结束,即跳过循环体重下面尚未执行的语句,接着进行下次的是否执行循环的判断。
continue可以用在for循环以及 while循环中,但是不建议用在while循环中,不小心容易死循环
*/

List操作

/**
   * 演示List方法
   *
   * 属性方法:
   * .length
   * .isNotEmpty
   * .isEmpty
   *
   * 操作方法:
   * .reversed
   * .first
   * .last
   * .join()
   * .add()
   * .addAll()
   * .insert()
   * .insertAll()
   * .split()
   */
  List list = ["xxx", "yyy", "zzz"];
  print(list.length);
  if (list.isNotEmpty) {
    print("list isNotEmpty");
  } else if (list.isEmpty) {
    print("list isEmpty");
  }
  //其他方式
  print(list.reversed);
  print(list.first);
  print(list.last);

  print(list.join("/")); //转成字符串
  list.add("xuqingsong");
  list.addAll(["mm","nn"]);
  list.insert(1, "insert");
  list.insertAll(2, ["111","222"]);
  print(list.join("/").split("/")); //字符串格式转成list模式

打印结果:
3
list isNotEmpty
(zzz, yyy, xxx)
xxx
zzz
xxx/yyy/zzz
[xxx, insert, 111, 222, yyy, zzz, xuqingsong, mm, nn]

Set集合

/**
   * Set集合测试,同List对比,Set集合不能添加相同的数据,自动去重
   */
  var set = new Set();
  set.add("香蕉");
  set.add("苹果");
  print(set);//打印结果:{香蕉, 苹果}
  set.add("香蕉");//打印结果中无重复的香蕉,被自动去重了
  set.add("菠萝");
  print(set);//打印结果:{香蕉, 苹果, 菠萝}

  Set set1 = {"小狗","小猫"};
  print(set1);
  //声明list列表,然后通过addAll实现添加到Set中,addAll接收的参数是迭代器Iterable
  List list = ["熊猫","骆驼","小狗"];//结果集合中,小狗被过滤掉了
  set1.addAll(list);
  print(set1);

打印的结果值:

{香蕉, 苹果}
{香蕉, 苹果, 菠萝}
{小狗, 小猫}
{小狗, 小猫, 熊猫, 骆驼}

Map映射是无序的键值对
映射(Maps)是无序的键值对:

常用属性:
    keys            获取所有的key值
    values          获取所有的value值
    isEmpty         是否为空
    isNotEmpty      是否不为空
常用方法:
    remove(key)     删除指定key的数据
    addAll({...})   合并映射  给映射内增加属性
    containsValue   查看映射内的值  返回true/false
    forEach   
    map
    where
    any
    every
 /**
   * Map测试:声明方式通集合set相似,
   * 由花括号括起来,只是里面的数据采用键值对的方式。
   * js中键可以没有单引号或双引号,但是dart中必须有,通java一样。
   */
  Map map = {
    "name": "xqs",
    "age": 19,
    "work": ["工程师", "设计师", "党员"]
  };
  print(map.keys.toList()); //将key值作为list输出
  print(map.values.toList()); //将value值作为list列表输出
  map.remove("xxx"); //这里会移除掉name的键值对
  print(map.keys.toList());

结果值:

[name, age, work]
[xqs, 19, [工程师, 设计师, 党员]]
[name, age, work]

集合的遍历:for/.forEach

Map map = {
    "name": "xqs",
    "age": 19,
    "work": ["工程师", "设计师", "党员"]
  };
  print("------分割线-------");
  //循环遍历方式1
  map.forEach((key, value) {
    print("$key----$value");
  });
  // for(int i=0;i<map.length;i++){//这种方式是无法取出值的
  //   print(map[i].toString());
  // }
  print("------分割线1-------");
  //循环遍历方式2
  List list = ["香蕉", "苹果", "榴莲"];
  for (var element in list) {
    //for(var x in y)这种方式不能用在map上,只能用在list和set上
    print(element + " >>>>  ");
  }

  for (int i = 0; i < list.length; i++) {
    print(list[i]+"!!!");
  }

  print("------分割2-------");
  Set mySet = {"香蕉", "苹果", "榴莲"};
  for (var element in mySet) {
    //for(var x in y)这种方式不能用在map上,只能用在list和set上
    print(element + "------");
  }

结果值:
------分割线-------
name----xqs
age----19
work----[工程师, 设计师, 党员]
------分割线1-------
香蕉 >>>>  
苹果 >>>>  
榴莲 >>>>  
香蕉!!!
苹果!!!
榴莲!!!
------分割2-------
香蕉------
苹果------
榴莲------

集合的遍历(可以用在list列表、map键值对、set集合上):map、where、any、every
map是循环变量出每一个value进行表达式运算后返回对应的list集合

where代表筛选出满足条件的value值

any代表list列表集合中有一个value值满足表达式则返回true,否则返回false。any遍历到满足条件的value值后不会再继续变量

every 代表list列表结婚中每一个value值都满足表达式筛选时返回true,否则返回false。
every会遍历完所有的列表值

/**
   * List 的map方法,循环遍历
   */
  List list = [1, 3, 4];
  // var newList = list.map((value) {
  //   return (value * 2);
  // });
  //等价于上面的表达式:map代表的是遍历取出value,然后返回对应的表达式
  var newList = list.map((value) => value * 2);
  print(newList);

  //where 代表每一个value满足这个表达式条件的筛选集合
  newList = list.where((value) => value < 4);
  print(newList.toList());
  //any方法,代表集合里有个满足条件就返回true
  bool flag = list.any((value) => value < 1);
  print(flag);
  //every方法代表集合中每一个值都满足条件,就返回true,否则返回false
  bool flag1 = list.every((value) => value < 5);
  print(flag1);
/**
   * List 的map方法,循环遍历
   */
  List list = [1, 3, 4];
  // var newList = list.map((value) {
  //   return (value * 2);
  // });
  //等价于上面的表达式:map代表的是遍历取出value,然后返回对应的表达式
  var newList = list.map((value) => value * 2);
  print(newList);

  //where 代表每一个value满足这个表达式条件的筛选集合
  newList = list.where((value) {
    print(value);
    return value < 4;
  });
  print(newList.toList());
  //any方法,代表集合里有个满足条件就返回true,经过print打印发现,
  //any寻找到满足条件后的值后不会再循环变量
  bool flag = list.any((value) {
    print(value);
    return value < 4;
  });
  print(flag);
  //every方法代表集合中每一个值都满足条件,就返回true,否则返回false
  bool flag1 = list.every((value) {
    print(value);
    return value < 5;
  });
  print(flag1);
}

结果值:

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

推荐阅读更多精彩内容

  • 一、变量和常量 虽然 Dart 是代码类型安全的语言,但是由于其支持类型推断,因此大多数变量不需要显式地指定类型:...
    momxmo阅读 450评论 0 1
  • 本文是对 Dart 语言的官方文档做了简单的翻译和总结,有不当之处敬请指正。如果有时间和精力建议通读官方文档 he...
    小小小超子阅读 10,509评论 8 22
  • 概览 一、运算符二、流程控制三、类和对象四、泛型五、库的使用 一、运算符 你可能会疑惑,Dart为什么要搞出这么多...
    得_道阅读 502评论 0 0
  • 变量 定义 dynamic和Object的区别dynamic:变量在运行时确定实际类型Object:变量在编译时确...
    AilurusFulgens阅读 380评论 0 1
  • 目录 前言 代码注释 变量和常量 数据类型 操作符 控制流 异常 前言 本篇开始讲解Dart语法,期间会通过对比J...
    地球是猿的阅读 1,133评论 0 0