dart学习-- Dart之基础语法

Posted lxlx1798

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dart学习-- Dart之基础语法相关的知识,希望对你有一定的参考价值。

一,重要概念

  • 所有你能够赋值给一个变量的都是一个对象,无论是变量,数字,函数等都是一个对象。所有的对象都是的一个实例。所有的对象都继承自内置的Object类。这一点类似于Java语言“一切皆对象”。
  • 虽然Dart是强类型语言,但是类型声明是可选项(即不是必须的),因为Dart可以自己去推断类型。这点与JS和Swift很类似。比如var number = 1,变量number就被推断为int类型。当你想明确说没有类型时,可以使用特殊类dynamic/object声明(详情下面会讲到)。
  • Dart代码在运行前解析。指定数据类型和编译时的常量,可以提高运行速度。
  • Dart支持泛型,像List<int>,一个整数列表。类比于OC中的NSArray<NSString *> *Array 声明。
  • Dart支持顶层函数,如main(),以及与类绑定的函数(静态方法),还有与对象绑定的函数(实例方法)。甚至可以在函数中创建函数(嵌套函数或局部函数)。
  • 同样,Dart支持顶级变量、静态变量和实例变量。实例变量即对象的属性。
  • 和Java不同的是,Dart没有public、protected和private的关键字。私有特性通过变量或者函数加上下划线来表示。
  • Dart的工具可以检查警告信息(warning)和错误信息(errors)。警告信息只是表示代码可能不工作,但是不妨碍程序运行。 错误信息可以是编译时错误,也可能是运行时的错误。 编译时的错误将阻止程序运行,运行时的错误将会以异常(exception)的方式呈现。
  • Dart支持 anync/await异步处理。

二,关键字(56个)

  • 33个保留字(不能使用保留字作为标识符)
关键字---
if superdo switch assert
else in this enum
is throw true break
new try case extends
null typedef catch var
class false void const
final rethrow while continue
finally return with for
default    
 
  • 内置标志符有:(17个)
 
关键字---
abstract deferred as dynamic
covariant export external factory
get implements import library
operator part set static
typedef  
  • Dart2相对于Dart1新增的,支持异步功能的关键字有:(6个)
关键字---
async async* await sync*
yield yield*
  • 跟java相比,Dart特有的关键字有:(25个)
关键字---
deferred as assert dynamic
sync* async async* in
is await export library
external typedef factory operator
var part const rethrow
covariant set yield get
yield*

三、变量和常量

(一)变量的声明,可以使用 var、Object 或 dynamic 关键字。

  创建变量并初始化变量实例:

  • Dart语言本质上市动态类型语言,类型是可选的;
  • 可以使用var声明变量,也可以使用类型(比如String)来直接声明变量。使用Var声明时,Dart可以自己去推断类型;
  • 使用Object 或 dynamic声明一个变量时可以被赋予不同类型的对象;
  • 但是大多数情况,我们不会去改变一个变量的类型;
//字符串赋值的时候,可以使用单引号,也可以使用双引号。
var str = "this is string vlaues."; //Dart可以自己去推断类型

变量存储引用。

  1. 使用Object或dynamic关键字
dynamic name = "张三";
  • 调用的变量name包含对String值为“张三” 的对象的引用。
  • name推断变量的类型是String,但可以通过指定它来更改该类型。
  • 如果对象不限于单一类型(没有明确的类型),请使用Object或dynamic关键字
Object name1 = "小明";
dynamic name2 = "老王";
  • 其实dynamic不是实际的type,而是类型检查开关。一个变量被dynamic修饰,相当于告诉static type 系统“相信我,我知道我自己在做什么”。
    例如
    dynamic d_name; //不要进行类型检查了。即使出错了,是我自己的责任。
    Object o_name;  //v_name不是别人,就是Object的实例化。(一切皆是继承于Object的对象,所以Object类型可以接受任何类型的对象)

   2. 显式声明将被推断的类型,比如String,int等。

  • 可以使用String显示声明字符串类型
    String str1 = "dart str";

(二)默认值

  • 未初始化的变量的初始值为null(包括数字),因为一切皆对象,因此数字、字符串都可以调用各种方法,这个我们上面有提到。
    //我们先声明一个int类型的变量
    int intDefaultValue;
    //assert 是语言内置的断言函数,仅在检查模式下有效
    //在开发过程中,除非条件为真,否则会引发异常。(断言失败则程序立即终止)
    assert(intDefaultValue == null);
    //打印结果为null, 说明数字类型初始化值为null
    print(intDefaultValue);

(三)Final and const

  • 如果您从未打算更改一个变量,那么使用 final 或 const,不是var,也不是一个类型。
  • 一个 final 变量只能被设置一次;const 变量是一个编译时常量。(Const变量是隐式的final。)
  • final的顶级或类变量在第一次使用时被初始化。
  1. 被final或者const修饰的变量,变量类型可以省略。
    //可以省略int类型的声明
    final test = 111;
    //等同于上面
    final int test = 111;
  2. 被 final 或 const 修饰的变量无法再去修改其值。
    //被final修饰的变量的值无法被改变
    final test1 = "test";
    //这样写会提示‘test1‘, a final variable, can only be set once
    test1 = "test1";
    //被const修饰的变量不能被重新赋值
    const test2 = 20.02;
    //这样写会提示 Constant variables can‘t be assigned a value
    test2 = 23.33;
  3. 注意:flnal 或者 const 不能和 var 同时使用会提示:Expected an identifier,
    //因为var是用来修饰变量的,而final修饰的变量称之为常量(不能改变,只能赋值一次),所以不能这么混合使用吧(我是这么理解的)
    final var test3 = true;
    //这一句提示这个:The const variable ‘var‘ must be initialized  
    //The name ‘var‘ is already defined.
    const var test4 = test4;
  4. 常量如果是类级别的,请使用 static const
    class Test
      static const name = "test";
       static main()
        //这里会报错:Undefined name ‘static‘
        //static类型的变量是属于类的,所以在类里面,方法之外
        static const name = "test";
       
    
  5. 常量的运算
    final speed = 200;//(km/h)
    final double distance = 2.5 * speed; // 距离 = 速度 * 时间
    
    const speed1 = 200;
    const double distance1 = 2.5 * speed1;
  6. const关键字不只是声明常数变量。也可以使用它来创建常量值,以及声明创建常量值的构造函数。 任何变量都可以有一个常量值。
    //注意:[] 创建的是一个空的list集合
    // const[] 创建一个空的、不可变的列表(EIL)
    var varList = const []; //varList 当前时一个EIL
    final finalList = const []; //finalList一直是EIL
    const constList = const []; //constList是一个编译时常量的EIL
    
    //可以更改非final、非const变量的值
    //即使它曾经具有const值也可以改变
    varList = [111, 222, 333];
    
    // 不能更改final变量或const变量的值
    // 这样写,编译器提示:a final variable, can only be set once
    // finalList = [];
    // 这样写,编译器提示:Constant variables can‘t be assigned a value
    // constList = [];
  7. 只要任何插值表达式是一个计算结果为null或数字,字符串或布尔值的编译时常量,那么文字字符串就是编译时常量。(关于$表达式和不同的数据类型后面会讲解。)
    //这些是常量字符串
    const aConstNum = 0;
    const aConstBool = true;
    const aConstString = a const string;
    
    //这些不是常量字符串
    var aNum = 0;
    var aBool = true;
    var aString = a string;
    
    //编译通过
    const validConstString = $aConstNum $aConstBool $aConstString;
    var validString = $aNum $aBool $aString;
    var invalidString = $aNum $aBool $aConstString;
    
    //编译器报错
    //报错:Const variables must be initialized with a constant value
    //const常量必须用const类型的值初始化
    const invalidConstString = $aConstNum $aConstBool $aNum;
  8. 到这里final 和 const我们就介绍完毕了,那么相信有些人肯定会有疑问,final 和 const到底有什么区别呢?带着这个疑问我们先看下面这段代码。
    //编译器通过
    var a = 1;
    final f = 3;
    const d = 2;
    final b = a;
    const c = d;
    //编译器报错
    //报错:Const variables must be initialized with a constant value
    const e = a;
    const g = f;
  • 从上面代码我们可以看出
    1. final 和 const的一个区别
     final 要求变量只能初始化一次,并不要求赋的值一定是编译时常量,可以是常量也可以不是。而 const 要求在声明时初始化,并且赋值必需为编译时常量。

   2. 第二个区别是它们初始化的时机不同

      final 是惰性初始化,即在运行时第一次使用前才初始化。而 const 是在编译时就确定值了。

四、内置数据类型

Dart中支持以下特殊类型:

  • numbers 数字
  • strings 字符串
  • booleans 布尔
  • lists (also known as arrays) list集合(也称为数组)
  • maps map集合
  • runes (for expressing Unicode characters in a string) 字符(用于在字符串中表示Unicode字符)
  • symbols 符号

(一)num 数字类型

  • num是数字类型的父类,有两个子类 int 和 double。
  • num类型包括基本的运算符,如+,-,/和*,位运算符,如>>,在int类中定义。
  • 如果num和它的子类没有你要找的东西,math库可能会找到。比如你会发现abs(),ceil()和floor()等方法。
  1. int类型

    int表示整数,int的取值不大于64位,具体取决于平台。在Dart VM上,值可以从 -2的63次方 到 2的63次方减1.

    整数是没有小数点的数字。示例如下:

    int intNum1 = 10 ;
    print(intNum1);
    int intNum2 = 0xDEADBEEF ;
    print(intNum2);
  2. double类型

    64位(双精度)浮点数,如IEEE 754标准所规定。

    如果一个数字包含一个小数,那么它就是一个double类型。示例如下:

    double doubleNum1 = 1.1;
    print(doubleNum1);
    double doubleNum2 = 1.42e5;
    print(doubleNum2);

(二)String类型

Dart里面的String是一系列 UTF-16代码单元。

  1. 可以使用单引号或双引号来创建一个字符串。
    String str1 = 单引号基本使用demo.;
    String str2 = "双引号基本使用demo.";
  2. 单引号或者双引号里面嵌套使用引号。
    //单引号里面嵌套单引号,必须在前面加反斜杠
    String str3 = 双引号里面有单引号it\‘s,必须在前面加反斜杠.;
    //双引号里面嵌套单引号(正常使用)
    String str4 = "双引号里面有单引号it‘s.";
    //单引号里面嵌套双引号(正常使用)
    String str5 = 单引号里面有双引号,编程开发初学必备语句"hello world";
    //双引号里面嵌套双引号,必须在前面加反斜杠
    String str6 = "双引号里面有双引号,编程开发初学必备语句\"hello world\"";
  3. 多个字符串相邻中间的空格问题:
    经测试发现,除了单引号嵌套单引号或者双引号嵌套双引号不允许出现空串之外,其余的几种情况都是可以运行的。
    示例如下:
    // 这个会报错
    //String blankStr1 = ‘hello‘‘‘‘world‘;
    // 这两个运行正常
    String blankStr2 = hello‘‘ ‘‘world; //结果: hello world
    String blankStr3 = hello‘‘_‘‘world; //结果: hello_world
    
    // 这个会报错
    //String blankStr4 = "hello""""world";
    // 这两个运行正常
    String blankStr5 = "hello"" ""world"; //结果: hello world
    String blankStr6 = "hello""_""world"; //结果: hello_world
    
    //单引号里面有双引号,混合使用运行正常
    String blankStr7 = hello""""world; //结果: hello""""world
    String blankStr8 = hello"" ""world; //结果: hello"" ""world
    String blankStr9 = hello""_""world; //结果: hello""_""world
    
    //双引号里面有单引号,混合使用运行正常
    String blankStr10 = "hello‘‘‘‘world"; //结果: hello‘‘‘‘world
    String blankStr11 = "hello‘‘ ‘‘world"; //结果: hello‘‘ ‘‘world
    String blankStr12 = "hello‘‘_‘‘world"; //结果: hello‘‘_‘‘world
  4. 可以使用相邻字符串文字或 + 运算符连接字符串:
    //直接把相邻字符串写在一起,就可以连接字符串了。
    String connectionStr1 = 字符串连接甚至可以在换行的时候进行。;
    //用+把相邻字符串连接起来。
    String connectionStr2 = 字符串连接+ 甚至可以在+ 换行的时候进行。;
    //使用单引号或双引号的三引号:
    String connectionStr3 = ‘‘‘ 
    你可以创建
    像这样的多行字符串。
    ‘‘‘ ;

     String connectionStr4 = """这也是一个
      多行字符串。""";

  5. 关于转义符号的使用
    声明raw字符串(前缀为r),在字符串前加字符“r”,或者在\前面再加一个\,
    可以避免“\”的转义作用,在正则表达式里特别有用
    
    举例如下:
    
    print(r"换行符:\n"); //这个结果是 换行符:\n
    print("换行符:\\n"); //这个结果是 换行符:\n
    print("换行符:\n"); //这个结果是 换行符:
  6. 可以使用$表达式将表达式的值放入字符串中。如果表达式是标识符,则可以跳过。
    为了获得对应于object的字符串,Dart调用object的toString()方法。
    String replaceStr1 = 字符串连接;
    print($replaceStr1
    + 甚至可以在换行的时候进行。 == 字符串连接
    + 甚至可以在换行的时候进行。);
    
    String replaceStr2 = android Studio;
    print(你知道 +
    $replaceStr2.toUpperCase()
    + 最新版本是多少吗? ==
    你知道ANDROID STUDIO最新版本是多少吗?);

  注:
    ==操作符测试两个对象是否相等。如果两个字符串包含相同的代码单元序列,那么它们是等效的。

(三)bool 布尔值

  • 为了表示布尔值,Dart有一个名为的类型bool。
  • 只有两个对象具有bool类型:true和false,它们都是编译时常量。
  • Dart的类型安全意味着您不能使用if(nonbooleanValue)或assert(nonbooleanValue)等代码。

相反,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 是语言内置的断言函数,仅在检查模式下有效

在开发过程中, 除非条件为真,否则会引发异常。(断言失败则程序立刻终止)。

(四)list 集合(也称为数组)

  • 几乎所有编程语言中最常见的集合可能是数组或有序对象组。
  • 在Dart中,数组是List对象,因此大多数人只是将它们称为List。
  • Dart list文字看起来像javascript数组文字。 以下是一个简单的Dart列表:
    //创建一个int类型的list
    List list = [10, 7, 23];
    print(list);
  • 要创建一个编译时常量const的list,示例如下:
    List constantList = const[10,3,15];
  • 注意事项:
    1.可以直接打印list包括list的元素,list也是一个对象。但是java必须遍历才能打印list,直接打印是地址值。
    2.和java一样list里面的元素必须保持类型一致,不一致就会报错。
    3.和java一样list的角标从0开始。

(五)map集合

  • 一般来说,Map是将键和值相关联的对象。键和值都可以是任何类型的对象。每个键都应该是唯一的,只能出现一次。Dart支持使用Map字面值或者map类型来创建Map。

  以下是使用Map字面值创建map的例子:

var skills = 
1: Java,
2: Python,
3: Dart
;
  • 注意:以上代码中,Dart推断skills的类型为Map<int, String>。如果尝试将错误类型的值添加到这个Map中,会引发错误。
    还可以使用Map的构造函数来得到相同的效果:
var skills = new Map();
skills[1] = Java;
skills[2] = Python;
skills[3] = Dart;

    也可以将新的键值对添加到现有的Map中:

skills[4] = C#;
  • 通过skills[键]的方法来访问其中的值,如果其中没有这个键,将会返回null。使用skills.length会得到键值对的个数。
  • 相关API

    1、添加元素。格式 变量名[key] = value;

        注意:key可以是不同类型。

    //添加一个新的元素,key为 4 value为 华为
    companys[4] = 华为; print(companys);//打印结果 first: 阿里巴巴, second: 腾讯, fifth: 百度, 4: 华为

    2、修改元素

    //把key为first的元素对应的value改成 alibaba
    companys[first] = alibaba; print(companys);//打印结果 first: alibaba, second: 腾讯, fifth: 百度, 4: 华为

    3、注意事项

    // map里面的value可以相同
    Map company1 =  first: 阿里巴巴, second: 腾讯, 5: 百度,new key: 阿里巴巴;
    print(company1); //打印结果 first: 阿里巴巴, second: 腾讯, 5: 百度, new key: 阿里巴巴
    
    Map company2 = new Map();
    company2[first] = 阿里巴巴;
    company2[second] = 腾讯;
    company2[fifth] = 百度;
    company2[new key] = 阿里巴巴; // map里面的value可以相同
    company2[new key2] = ‘‘; // map里面value可以为空字符串
    company2[new key3] = null; // map里面的value可以为null
    print(company2); //打印结果 first: 阿里巴巴, second: 腾讯, fifth: 百度, new key: 阿里巴巴, new key2: , new key3: null

    4、要创建一个编译时常量const的map,请在map文字之前添加const:

    final fruitConstantMap = const 2: apple,10: orange,18: banana;

    小结:

    1.创建map有两种方式。 
    2.map的key类型不一致也不会报错。 
    3.添加元素的时候,会按照你添加元素的顺序逐个加入到map里面,哪怕你的key,比如分别是 1,2,4,看起来有间隔,事实上添加到map的时候是1:value,2:value,4:value 这种形式。 
    4.添加的元素的key如果是map里面某个key的英文,照样可以添加到map里面。 
    5.map里面的key不能相同。但是value可以相同,value可以为空字符串或者为null。

(六)runes (for expressing Unicode characters in a string) 字符(用于在字符串中表示Unicode字符)

  • Unicode为世界上所有的书写系统中使用的每个字母,数字和符号定义了唯一的数值。
  • 由于Dart字符串是UTF -16代码单元的序列,所以在字符串中表达32位Unicode值需要特殊的语法。
    表示Unicode代码点的常用方法是\uXXXX,其中XXXX是一个4位十六进制值。
  • 例如,心形字符()是\u2665。
    要指定多于或少于4个十六进制数字,请将该值放在大括号中。 例如,笑的表情符号()是\u1f600。
  • String类有几个属性可以用来提取符文信息。 codeUnitAt和codeUnit属性返回16位代码单元。使用Runes属性来获得一个string的符文。

  以下示例说明了符文,16位代码单元和32位代码点之间的关系。

var clapping = \u1f44f; 
print(clapping); 
print(clapping.codeUnits); 
print(clapping.runes.toList()); //这里使用String.fromCharCodes方法显示字符图形
//String的详细api后面会具体讲解。
Runes input = new Runes( \u2665 \u1f605 \u1f60e \u1f47b \u1f596 \u1f44d); 
print(new String.fromCharCodes(input));

(七)symbols 符号

有两个 #radix   #bar  可以使用
官网文档没看明白这个具体是做什么的。。暂且放着。
这个用的很少,基本用不到的。

 

 

 

 

以上是关于dart学习-- Dart之基础语法的主要内容,如果未能解决你的问题,请参考以下文章

Dart语法学习-基础-类

Dart语法篇之面向对象基础

Dart语法学习-基础 流程控制异常类

Flutter基础组件01Text

Flutter基础组件01Text

Flutter基础组件08BottomNavigationBar