美文网首页Flutter
初识Flutter及Dart语言简介

初识Flutter及Dart语言简介

作者: 不一样的色彩 | 来源:发表于2020-10-20 21:53 被阅读0次

    Flutter官方提供的Flutter框架图

    http://cdn.myweimai.com/images/f8e41fa56e0a7397f4f16afd216509cf_769x417.png

    Flutter Framework

    这是一个纯 Dart实现的 SDK,它实现了一套基础库,自底向上,我们来简单介绍一下:

    • 底下两层(Foundation和Animation、Painting、Gestures)在Google的一些视频中被合并为一个dart UI层,对应的是Flutter中的dart:ui包,它是Flutter引擎暴露的底层UI库,提供动画、手势及绘制能力。
    • Rendering层,这一层是一个抽象的布局层,它依赖于dart UI层,Rendering层会构建一个UI树,当UI树有变化时,会计算出有变化的部分,然后更新UI树,最终将UI树绘制到屏幕上,这个过程类似于React中的虚拟DOM。Rendering层可以说是Flutter UI框架最核心的部分,它除了确定每个UI元素的位置、大小之外还要进行坐标变换、绘制(调用底层dart:ui)。
    • Widgets层是Flutter提供的的一套基础组件库,在基础组件库之上,Flutter还提供了 Material 和Cupertino两种视觉风格的组件库。而我们Flutter开发的大多数场景,只是和这两层打交道

    Flutter Engine

    这是一个纯 C++实现的 SDK,其中包括了 Skia引擎、Dart运行时、文字排版引擎等。在代码调用 dart:ui库时,调用最终会走到Engine层,然后实现真正的绘制逻辑。

    总结

    Flutter框架本身有着良好的分层设计,本节旨在让读者对Flutter整体框架有个大概的印象,相信到现在为止,读者已经对Flutter有一个初始印象,在我们正式动手之前,我们还需要了解一下Flutter的开发语言Dart。

    Dart语言简介

    Dart的设计目标应该是同时借鉴了Java和JavaScript。Dart在静态语法方面和Java非常相似,如类型定义、函数声明、泛型等,而在动态特性方面又和JavaScript很像,如函数式特性、异步支持等。除了融合Java和JavaScript语言之所长之外,Dart也具有一些其它具有表现力的语法,如可选命名参数、..(级联运算符)和?.(条件成员访问运算符)以及??(判空赋值运算符)。其实,对编程语言了解比较多的读者会发现,在Dart中其实看到的不仅有Java和JavaScript的影子,它还具有其它编程语言中的身影,如命名参数在Objective-C和Swift中早就很普遍,而??操作符在PHP 7.0语法中就已经存在了,因此我们可以看到Google对Dart语言给予厚望,是想把Dart打造成一门集百家之所长的编程语言。

    2.1 变量声明

    1. var

    类似于JavaScript中的var,它可以接收任何类型的变量,但最大的不同是Dart中var变量一旦赋值,类型便会确定,则不能再改变其类型,如:

    var t;
    t = "hi world";
    // 下面代码在dart中会报错,因为变量t的类型已经确定为String,
    // 类型一旦确定后则不能再更改其类型。
    t = 1000;
    

    上面的代码在JavaScript是没有问题的,前端开发者需要注意一下,之所以有此差异是因为Dart本身是一个强类型语言,任何变量都是有确定类型的,在Dart中,当用var声明一个变量后,Dart在编译时会根据第一次赋值数据的类型来推断其类型,编译结束后其类型就已经被确定,而JavaScript是纯粹的弱类型脚本语言,var只是变量的声明方式而已。

    1. dynamic和Object

    Object 是Dart所有对象的根基类,也就是说所有类型都是Object的子类(包括Function和Null),所以任何类型的数据都可以赋值给Object声明的对象. dynamic与var一样都是关键词,声明的变量可以赋值任意对象。 而dynamic与Object相同之处在于,他们声明的变量可以在后期改变赋值类型。

    dynamic t;
     Object x;
     t = "hi world";
     x = 'Hello Object';
     //下面代码没有问题
     t = 1000;
     x = 1000;
    

    dynamic与Object不同的是,dynamic声明的对象编译器会提供所有可能的组合, 而Object声明的对象只能使用Object的属性与方法, 否则编译器会报错。如:

    dynamic a;
     Object b;
     main() {
         a = "";
         b = "";
         printLengths();
     }   
    
     printLengths() {
         // no warning
         print(a.length);
         // warning:
         // The getter 'length' is not defined for the class 'Object'
         print(b.length);
     }
    

    变量a不会报错, 变量b编译器会报错

    dynamic的这个特性与Objective-C中的id作用很像. dynamic的这个特点使得我们在使用它时需要格外注意,这很容易引入一个运行时错误.

    2.final和const

    如果您从未打算更改一个变量,那么使用 final 或 const,不是var,也不是一个类型。 一个 final 变量只能被设置一次,两者区别在于:const 变量是一个编译时常量,final变量在第一次使用时被初始化。被final或者const修饰的变量,变量类型可以省略,如:

    //可以省略String这个类型声明
    final str = "hi world";
    //final String str = "hi world"; 
    const str1 = "hi world";
    //const String str1 = "hi world";
    

    2.2 函数

    Dart是一种真正的面向对象的语言,所以即使是函数也是对象,并且有一个类型Function。这意味着函数可以赋值给变量或作为参数传递给其他函数,这是函数式编程的典型特征。

    1. 函数申明
    bool isNoble(int atomicNumber) {
      return _nobleGases[atomicNumber] != null;
    }
    

    Dart函数声明如果没有显式声明返回值类型时会默认当做dynamic处理,注意,函数返回值没有类型推断:

    typedef bool CALLBACK();
    
    //不指定返回类型,此时默认为dynamic,不是bool
    isNoble(int atomicNumber) {
      return _nobleGases[atomicNumber] != null;
    }
    
    void test(CALLBACK cb){
       print(cb()); 
    }
    //报错,isNoble不是bool类型
    test(isNoble);
    

    2.对于只包含一个表达式的函数,可以使用简写语法

    bool isNoble (int atomicNumber)=> _nobleGases [ atomicNumber ] != null ;
    

    3.函数作为变量

    var say = (str){
      print(str);
    };
    say("hi world");
    

    4.函数作为参数传递

    void execute(var callback) {
        callback();
    }
    execute(() => print("xxx"))
    

    5.可选的位置参数

    包装一组函数参数,用[]标记为可选的位置参数,并放在参数列表的最后面:

    String say(String from, String msg, [String device]) {
      var result = '$from says $msg';
      if (device != null) {
        result = '$result with a $device';
      }
      return result;
    }
    

    下面是一个不带可选参数调用这个函数的例子:

    say('Bob', 'Howdy'); //结果是: Bob says Howdy
    

    下面是用第三个参数调用这个函数的例子:

    say('Bob', 'Howdy', 'smoke signal'); //结果是:Bob says Howdy with a smoke signal
    

    6:可选的命名参数

    定义函数时,使用{param1, param2, …},放在参数列表的最后面,用于指定命名参数。例如:

    //设置[bold]和[hidden]标志
    void enableFlags({bool bold, bool hidden}) {
        // ... 
    }
    

    调用函数时,可以使用指定命名参数。例如:paramName: value

    enableFlags(bold: true, hidden: false);
    

    可选命名参数在Flutter中使用非常多。

    注意,不能同时使用可选的位置参数和可选的命名参数

    相关文章

      网友评论

        本文标题:初识Flutter及Dart语言简介

        本文链接:https://www.haomeiwen.com/subject/lusjmktx.html