• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Flutter学习之Dart语法特性

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

一、前言

第一天把Flutter环境搭建了,并简单实现第运行第一个Flutter项目,感觉很不错,一些基本操作和原生体验差不多。用Flutter框架写过App项目的开发者都知道,Flutter是一个使用Dart语言开发的跨平台移动UI框架,通过自建绘制引擎,能高性能、高保真地进行Android和IOS开发。可能很多开发者都会像我一样,会有个疑问?为什么Flutter会选择Dart呢?我特意查了下网上资料,总结以下下面六点:

  • Dart在release下是AOT(Ahead Of Time, 运行前,比如普通的静态编译)编译的,编译成快速、可预测的本地代码,使Flutter几乎都可以使用Dart编写,在Debug下,Dart是JIT(jUST In Time 运行时编译,边运行边编译,java虚拟机就用到)编译,开发周期快,就好像Flutter亚热级的热重载。
  • Dart可以更轻松地创建以60fps运行的流畅动画和转场,60fps是一个什么概念呢?我相信王者荣耀大家都知道,王者荣耀的游戏时帧率评测报告是在40fps-50fps中,越高的fps会提供更快速的操控流畅度,体验感更舒适。
  • Dart可以在没有锁的情况下进行对象分配和垃圾回收。像JavaScript一样,Dart避免了抢占式调度和共享内存,大多数支持并发执行线程的计算机语言(Java、Kotlin、Swift)都使用抢占式来切换线程,抢占就会产生竞态条件,竞态条件很有可能导致严重错误,如应用程序崩溃导致数据丢失等等,一般解决竞态条件使用来保护,但是锁本身可能导致卡顿,也有可能产生死锁,而Dart针对这个问题,采取了isolate方法来解决,Dart中的线程称为isolate,不共享内存。那么Dart是单线程的,意味根本不允许抢占。单线程有助于开发者确保关键功能(动画和转场)完成而无需抢占。 Flutter应用程序被编译为本地代码,因此它们不需要再领域之间建立缓慢的桥梁,所以启动速度快得多。
  • Dart使Flutter不需要单独的声明式布局语言,如JSX或XML,或者单独的可视化界面构建器。其实针对这点我觉得Android的XML界面构建器是很直观阅读的。
  • Dart容易学习,具有静态和动态语言用户都熟悉的特性。
  • 易于移植,Dart可编译成ARM和X86代码,这样Dart移动应用程序可以在IOS、Android和其他地方运行。

那知道Flutter为什么选择Dart之后,作为开发Flutter项目来讲,把Dar学好就很有必要了,下面就从基本语法开始对Dart入门。

二、Dart环境

1.本地环境

我这边本地是用IntelliJ IDEA来编写Dart项目,我这边简单说一下环境配置流程:

  1. 下载Flutter sdk 之前下载过,在第一天配置Android Stdio环境有说。
  2. Dart插件的安装,Windows下选择FileSettingPlugins搜索Dart下载,而Mac下选择屏幕左上角IntelliJ IDEAPerferencesPlugins,如下图:


下载完重启即可。

  1. 配置Dart SDK位置,Windows下选择FileSettingLanguages & FrameworksDartDart SDK Path配置,而Mac下选择屏幕左上角IntelliJ IDEAPerferencesLanguages & Frameworks,如下图:


4.在FileNewProjectDart,选择Dart语言,如下图:

  1. 创建项目名字,设置项目路径,如下图:


6. 最后点击Finish按钮,会看到项目已经被创建了,如下图:

2.网页环境

除了上面通过IntelliJ IDEA本地配置环境外,如果觉得上面配置Dart环境太麻烦就走网页环境,就是下面这个链接直接在线编写Dart小语法练习项目https://dartpad.dartlang.org/,下面例子是循环输出5个hello,示意图如下:

看还是很方便快捷的注意:可能需要 F-Q 才能运行出结果.

三、Dart一些概念

  • 在Dart中,一切都是对象,所有的对象都是继承Object,也就是所有能够使用变量引用的都是对象,每个对象都是一个了类的实例。在Dart中甚至数字、方法和null都是对象。
  • 没有赋初值的变量都会有默认值null
  • 标识符可以以字母或者_下划线开头,后面可以是其他字符和数字的组合。
  • Dart支持顶级方法,如main方法,同时还支持在类中定义函数(静态函数和实例函数),还可以在方法中定义方法,Dart支持顶层变量,也支持类变量或对象变量。
  • Dart没有publicprotectedprivate关键字。如果某个变量以下划线_开头,代表这个变量是在库中是私有的。
  • Dart中的类和接口都是统一的,类即是接口,你可以继承一个雷,也可以实现一个类,自然也包含了良好的面向对象和并发编程的支持。
  • final的值只能被设定一次。const是一个编译时的常量,可以通过const来创建常量值,var n = const[],这里n还是一个变量,只是被赋值了一个常量值,它还是可以符其他值。实例变量可以是final,但不能是const。
  • Dart是强类型语言,但可以用var或者dynamic来声明一个变量,Dart会自动推断其数据类型,dynamic类似C#
  • 使用静态类型可以更清晰表面你的意图,并且可以让静态分析工具来分析你的代码。
  • Dart在运行之前会先解析你的代码。你可以通过使用类型或者编译时常量来帮助Dart去捕获异常以及让代码运行的更高效。
  • Dart工具可以指出两种问题:警告和错误。警告只是说你的代码可能有问题,但是并不会阻止你的代码执行。错误可以是编译时错误也可以是运行时错误。遇到编译时错时,代码将无法执行;运行时错误将会在运行代码的时候导致一个异常。

四、Dart语法

1.关键字

下表是Dart语言的关键字

const null class new this
as default final continue throw
assert deferred finally operator true
async do for part try
async* dynamic get rethrow typedef
await else if return var
break enum implements set void
case export import static while
catch external in super with
false extends is switch yield
abstract factory library sync* yield*

2.一个最基本的Dart程序

//定义打印数字方法
printNumber(num Number){
  print('The number is $Number');
}

//执行程序入口
void main(){
  //定义初始化一个变量
  var number = 6.76;
  //调用打印数字方法
  printNumber(number);
}

上面是一个简单基本的Dart程序,虽然简单但是用到了Dart很多特性:

  • //这是注释符号,还可以用/*...*/这是很多语言的注释符号
  • num这是数值型,Stringintbool是另外其他几种类型。注意:数值型num包含整形int和浮点型double
  • 6.76是一个数字常量,数字常量是编译时常量。
  • print()打印内容的方法
  • "..."或者是'...'表示字符串常量
  • $variableName或者是${expression}是字符串插值:在字符串常量中引用变量或者表达式
  • var一种不指定类型声明变量的方式
  • main()是Dart程序的入口方法,每个程序都需要一个这样得分方法

3.Variables变量

var name = 'knight';
上面是声明变量并赋值的示例,变量是一个引用,上面的名字为name的变量引用一个内容为"knight"的String对象。

4.Default value(默认值)

没有初始化的变量自动获取一个默认值为null。类型为数字的变量如果没有初始化那么默认的值也是null,因为数字类型也是对象,上面直接上代码:

//定义打印数字方法
printNumber(num Number){
  print("The number is $Number");
}

//执行程序入口
void main(){
  //定义初始化一个变量
  var number;

  //调用打印数字方法
  printNumber(number);
}

上面打印的结果是The number is null

5.Optional types(可选的类型)

声明变量的时候,可以选择加上具体类型,如下面:

  //定义初始化一个变量
  double number = 6.666;

添加类型可以更加清晰表达你的意图。IDE编译器等工具有可以使用类型来更好的帮助,提供提示代码补全,提前发现bug等功能。

6.Final and const

如果以后不打算修改一个变量,使用final或者const。一个final变量只能赋值一次;一个const变量是编译时常量。注意:const变量同时也是final变量,实例变量可以为final但不能是const。直接上例子:

//定义初始化一个变量
  final double number = 6.666;
  number = 6.667;
  //调用打印数字方法
  printNumber(number);

上面例子用final修饰number并赋值,但number = 6.67的时候,想重新给number再赋值的时候,编译错报错:number,a final variable,can only be set once.,意思和上面所说的一样就是final变量只能赋值一次!下面改为定义为const来修饰number:

  //定义初始化一个变量
  const double number = 6.666;
  number = 6.667;
  //调用打印数字方法
  printNumber(number);

同样number = 6.667编译器会报错Constant variables can not be assigned a value意思是常量值不能赋值,上面也说了,因为const变量同时也是final变量。如果const变量在类中,请定义为static const。可以直接定义const和旗初始值,也可以定义一个const变量使用其他const变量的值来初始化其值,如下面:

  //定义初始化一个变量
  const double number = 6.66;
  const double number1 = 2 * number;

上面例子的number1就是用了number来将自己初始化值,const关键字不仅仅只用来定义常量。有可以用来创建不变的值,还能定义构造函数为const类型
,这中类型的构造函数创建的对象是不可改变的,任何变量都可以有一个不变的值。

7.Built-in types(内置的类型)

在Dart有几种内置的数据类型:数值型-Number、布尔型-boolean、键值对-Map、字符串-String、列表-List、其他类型-Runes、Symbols

7.1数值型-Number

Dart中提供了两种类型:

//执行程序入口
void main(){


  //整形,其取值通常位于-2的53次方到2的53之间。
  num x = 777;
  //浮点数 64位
  x = 777.7;

  int y = 777;
  y = 777.7;       //这一行编译器会报错,因为将int型的数据转为double型

  double n = 77,7;
  d = 77;          //这个地方会报错,因为将double

  int x1 = 7;
  int x2 = 77;
  int x3 = 777;
  int x4 = 7777;

  print('${x1.bitLength}'); //占了3个bit 相当于00000000 00000111
  print('${x2.bitLength}'); //占了7个bit 相当于00000000 01001101
  print('${x3.bitLength}'); //占了10个bit 相当于00000011 00001001
  print('${x4.bitLength}'); //占了13个bit 相当于00011110 01100001


}

上面例子可以看到三个点:

  • 使用num声明的变量,可以随意的转换类型,如果使用int或者double明确的声明,那就不能转换了
  • 判断一个int值需要多少位时,可以使用bitLength

8.数值型的操作

运算符:+、-、*、/、~/、%
常用属性:isNaN、isEven、isOdd
常用方法:abs()、round()、floor()、ceil()、toInt()、toDouble()

//执行程序入口
void main(){


  int i =7;
  double d = 10.1;

  print(i / d);               //0.6930693069306931
  print(i ~/ d);              //0   这个操作是取整 就是得出商

  print(i.isOdd);             // 判断是奇数
  print(i.isEven);            // 判断是偶数


  //String -> int
  var x1 = int.parse("7");
  print(x1 == 7);              //输出true

  //Sting -> double
  var x2 = double.parse("7.7");
  print(x2 == 7.7);             //输出true

  //int -> String
  var x3 = 7.toString();
  print(x3 == '7');             //输出true

  //double -> String
  var x4 = 7.1234.toStringAsFixed(2);
  print(x4 == '7.12');          //输出true

  //求绝对值
  var x5 = (-7).abs();
  print(x5 == 7);

  //四舍五入1
  var x6 = (7.7).round();
  print(x6);                   //输出8

  //四舍五入2
  var x7 = (7.3).round();
  print(x7);                   //输出7

  //求大小于它的最大整数
  var x8 = (7.7).floor();
  print(x8);                   //输出7

  //求大于它的最小整数
  var x9 = (7.7).ceil();
  print(x9);                   //输出8

  double num1 = 7.77;
  print(num1);                //结果是7.77
  double num2 = 7;
  print(num2);                //结果是7.0
  int num3 = 7;
  print(num3.toDouble());     //int 转 double 结果是7.0
  double num4 = 7.77;
  print(num4.toInt());        //double 转 int 结果是7
  
}

上面列出了一些平时遇到最多的操作,如求余,求整,类型转换等。

9.Strings(字符串)

Dart字符串是UTF-16编码的字符序列,可以使用单引号或者双引号来创建字符串:

//执行程序入口
void main(){

  String m_str1 = '单引号字符串';
  String m_str2 = "双引号字符串";

  print(m_str1);        //输出:单引号字符串
  print(m_str2);        //输出:双引号字符串

}

String中单、双引号互相嵌套情况

//执行程序入口
void main(){

  String m_str1 = '单引号中的"双引号"字符串';
  String m_str2 = "双引号中的'单引号'字符串";

  print(m_str1);        //输出:单引号中的"双引号"字符串
  print(m_str2);        //输出:双引号中的'单引号'字符串

  //单引号里面有单引号,必须在前面加反斜杠
  String m_str3 = '单引号中的\'单引号\'';
  String m_str4 = "双引号里面有双引号,\"双引号\"";
  print(m_str3);        //输出:单引号中的'单引号'
  print(m_str4);        //输出:双引号里面有双引号,"双引号"

}

单引号嵌套单引号之间不允许出现空串(不是空格),双引号嵌套双引号之间不允许出现空串:

 //String m_str5 = '单引号''''单引号'; //报错
  String m_str6 = '单引号'' ''单引号';
  print(m_str6);        //输出: 单引号 单引号

  String m_str7 = '单引号''*''单引号';
  print(m_str7);        //输出: 单引号*单引号

  //String m_str8 = "双引号""""双引号";   //报错

  String m_str9 = "双引号"" ""双引号";
  print(m_str9);        //输出: 双引号 双引号

  String m_str10 = "双引号""*""双引号";
  print(m_str10);       //输出: 双引号*双引号

单双引号混合嵌套空串是可以的,如下:

 String m_str11 = '单引号""""单引号';
  print(m_str11);       //输出: 单引号""""单引号

  String m_str12 = '单引号"" ""单引号';
  print(m_str12);       //输出: 单引号"" ""单引号

  String m_str13 = '单引号""*"""单引号';
  print(m_str13);       //输出: 单引号""*"""单引号

  String m_str14 = "双引号''''双引号";
  print(m_str14);       //输出:  双引号''''双引号

  String m_str15 = "双引号'' ''双引号";
  print(m_str15);       //输出:  双引号'' ''双引号

  String m_str16 = "双引号''*''双引号";
  print(m_str16);       //输出:  双引号''*''双引号

字符串拼接方式,如下:

//使用空格拼接,多个空格也是可以地
  String m_str1 = '单引号字符串' '拼接'     '---';
  print(m_str1);       //输出:单引号字符串拼接---

  //使用换行符和空格
  String m_str2 = '单引号字符串'
    '换行''加空格' '';
  print(m_str2);       //输出: 单引号字符串换行加空格

  //单双引号 空格拼接
  String m_str3 = "单双引号字符串加空格" '拼接'      "----";
  print(m_str3);      //输出: 双引号字符串加空格拼接----

  //单双引号 换行 空格
  String m_str4 = "单双引号字符串"
    '换行' '加空格' '***';
  print(m_str4);      //输出: 单双引号字符串换行加空格***

  //使用三个单引号创建多行字符串
  String m_str5 = '''
     三个单引号+
     拼接
     ''';
  print(m_str5);      /*输出    三个单引号+
                                拼接
                                */

  //使用三个双引号创建多行字符串
  String m_str6 = """
    三个双引号+
    拼接
    """;
  print(m_str6);      /*输出    三个双引号+
                                拼接
                                */

  String m_str7 = "正常拼接"+",用加号了来拼接";
  print(m_str7);      //输出: 正常拼接,用加号了来拼接

通过提供一个r前缀可以创建"原始raw"字符串,在字符串加字符,或者在\前面再加一个\,可以避免\的转义作用,如下:

  String m_str1 = r"sdsdsds";
  print(m_str1);  //输出  sdsdsds

  print("换行:\n"); //输出:换行

  print(r"换行:\n"); //输出:换行:\n

  print("换行:\\n"); //输出:换行:\n

${表达式的使用},类似JS中ES6的表达式使用,使用$可以获取字符串的内容,用${表达式}可以将表达式的值放入字符串中,使用${表达式}也可以使用字符串拼接。下面也是直接上例子:

bool flag = true;
  String m_str1 = "字符串";
  print("看看这个值:${m_str1} ""看看这个值flag:${flag}"); //输出:字符串:字符串 看看这个值flag:true

  //使用$+字符串
  String name = "knight";
  print("$name" + "CTO");     //输出:knightCTO;

  //使用字符串拼接,运用了String类中的toUpperCase函数,把字母变成大写 
  String m_str = "Android";
  assert('${m_str.toUpperCase()} is very good' ==       
        'ANDROID is very good');
  

==操作符判断两个对象的内容是否一样,如果了;两个字符串包含一样的字符编码序列,则他们是相等的。在生产模式 assert() 语句被忽略了。在检查模式assert(condition) 会执行,如果条件不为 true 则会抛出一个异常。

10.Boolean(布尔值)

Dart中以bool代表布尔值,只有两个对象是布尔类型的,那就是truefalse所创建的对象,这两个对象都是编译时常量。当Dart需要一个布尔值,只有true对象才被认为是true,所有其他值都是false。看下下面的例子:

  String name ="knight";
  //报错 因为name不是bool类型
  if(name){
    print(name);

  }

上面代码会抛出异常,提示name不是布尔值,Dart使用的是先式的检查值,如下图:

  // 检查是否为空字符串
  var fullName = '';
  assert(fullName.isEmpty);

  // 检查是否小于等于0
  var hitPoints = 0;
  assert(hitPoints <= 0);

  // 检查是否为 null.
  var unicorn;
  assert(unicorn == null);

  // 检查是否为 NaN.
  var iMeantToDoThis = 0 / 0;
  assert(iMeantToDoThis.isNaN);

assert是语言内置的断言的函数,仅在检查模式有效,在开发过程中,除非条件为真,否则会引发异常。(断言失败则程序立刻终止)

11.Lists列表

array是编程语言中最常见的集合类型,我相信身为开发者,都用过。在Dart中数组就是List对象,所以一般称为lists,下面直接上Dart list的示例:

//创建一个int类型的list 并赋值为0,1,2,3,4
  List list =  [0,1,2,3,4];

  //使用构建的方式创建list
  List list1 = new List();

  //创建一个常量的List,不可以改变的List
  List list2 = const[0,1,2,3];

  //增加泛型
  List list3 = new List<String>();

  //创建固定的长度的数组列表,不能移除或者增加
  List list4 = new List(5);

  //创建包含所有以下元素的可改变的长度列表
  List list5 = new List.from([0,1,2,3]);

  //创建在固定范围内改变长度的列表
  List list6 = new List()..length = 10;

  //创建包含所有元素的固定长度列表
  List list7 = new List.unmodifiable([0,1,2]);

  //用生成器给所有元素赋初始值
  List list8 = new List<int>.generate(5, (int i){
    return i + i;

  });

List常用的一些api:

 //在列表中存放不同类型的对象
  List list = [1,2,3,false,"Kinght"];
  print(list);          //输出:[1, 2, 3, false, Kinght]

  //在列表中添加元素
  list.add(7);
  print(list);          //输出:[1, 2, 3, false, Kinght, 7]

  //修改列表下标为1的值
  list[1] = "paul";
  print(list);          //输出:[1, paul, 3, false, Kinght, 7]

  //移除列表的指定值得的元素
  list.remove("paul");
  print(list);          //输出:[1, 3, false, Kinght, 7]

  //移除列表指定下标下的元素
  list.removeAt(0);
  print(list);          //输出:[3, false, Kinght, 7]

  //获取列表的长度
  print(list.length);   //输出:4

  //向列表中的指定位置添加元素 在第0的位置上插入Android
  list.insert(0, "Android");
  print(list);          //输出:[Android, 3, false, Kinght, 7]

  //判断数组中是否有某元素
  print(list.indexOf("Android")); //这里存在,输出对应的下标,如果没有则输出-1

  //排序
  List list1 = [3,1,2,6,7];
  // 根据语法提示: List.sort([(int, int) → int compare]) → void
  list1.sort((a,b) => a.compareTo(b));
  print(list1);           //输出:[1, 2, 3, 6, 7]

简单总结:

  1. 下标索引从0开始。
  2. 可以直接打印List的元素,List也是一个对象。

12.Maps

通常来讲,Map是一个键值对相关的对象,键和值可以是任何类型的对象。每个键只出现一次,而一个值则可以出现多次。上面直接上Map集合的创建方式:

  //1.通过构建器来创建Map
  Map map1 = new Map();
  //添加值 赋值
  map1["one"] = 'Android';
  map1["two"] = 'IOS';
  map1["three"] = 'Flutter';
  print(map1);              //输出:{one: Android, two: IOS, three: Flutter}

  //2.通过复制的形式
  Map map2 = Map.of(map1);
  print(map2);              //输出:{one: Android, two: IOS, three: Flutter}

  //3 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
dart基础----dart语法入门发布时间:2022-07-13
下一篇:
MDT 2012 新功能,集成DaRT发布时间:2022-07-13
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap