zoukankan      html  css  js  c++  java
  • 【dart学习】-- Dart之函数

    1. 指定返回值得函数

    /**
    * 无返回值的函数
    * params: 可以是任意类型(var和Object类型也可以任意类型)。 当然这里的参数类型你可以随意指定我这里已dynamic为例
    * 参数类型:你也可以指定var、Object等,再比如说你可以指定num, int,double, String....
    * 如果我们对参数没有限制的话可以使用这个
    */
    void printDynamicParams(dynamic params){
      print(params);
    }

    主函数中我们调用printDynamicParams函数:

    main(List<String> arguments) {
      printDynamicParams(12.33);
      printDynamicParams('liyahong');
      printDynamicParams("Dart Method test");
      printDynamicParams(10);
      printDynamicParams(true);
    }

    控制台输出结果:

     

    这里我们可以传入任意类型,适用于参数类型不固定的情况使用。这里大家可能会有一个疑惑,包括我当时学习的时候也有这个疑惑,既然dynamic、var、Object都可以指定任意类型,那它们有什么区别吗?下面我们就来说下这个问题。

    • (1)var

      var是C# 3中引入的,其实它仅仅只是一个语法. var本身并不是一种类型, 其它两者object和dynamic是类型。var声明的变量在赋值的那一刻,就已经决定了它是什么类型。

      如果你这样使用,就会有编译错误:

      var a = 1;
      a = "Test";
    • (2)Object

      object之所以能够被赋值为任意类型的原因,其实都知道,因为所有的类型都派生自object. 

      它可以赋值为任何类型:

      object a = 1;
      a = "Test";
    • (3)dynamic

      dynamic不是在编译时候确定实际类型的, 而是在运行时。

      所以下面的代码是能够通过编译的,但是会在运行时报错:

      dynamic a = "test";
      a++;

    2. 不指定返回值类型的函数

    /**
    * 我们可以不指定返回值类型,这样的函数返回值默认为Object,也就是说你可以返回任意类型
    * params: 可以是任意类型
    */
    printReturnObjectParams(Object params){
      print(params);
      return params;
    }
    
    printObjectParams(Object params){
      print(params);
    }
    主函数中我们调用printReturnObjectParams 和 printObjectParams函数:
    main(List<String> arguments) {
      print(printReturnObjectParams("liyahong"));
      print(printReturnObjectParams(111));
      print(printReturnObjectParams(12.36));
      print(printObjectParams(true));
      printObjectParams('test');
    }

    控制台输出结果:

     

    由上面的结果可以看出,如果没有返回值得时候默认将会返回null。

    3.如果你的函数中只有一个表达式,你可以使用快速写法

    /**
    * 无返回值类型函数的快速写法
    * 注意:这种写法只适用于无返回值 并且 函数体中仅有一个表达式的函数。
    */
    void printNumber(num number) => print(number);

    主函数中我们调用printNumber函数:

    main(List<String> arguments) {
      printNumber(123);
      printNumber(22.3333);
    }

    控制台输出结果:

     

    这里我们提到了num关键字,在上篇博客中没有讲到,这里简单说一下。

    我们先看一下官方对它的说法:

    /**
    * An integer or floating-point number.
    * It is a compile-time error for any type other than [int] or [double]
    * to attempt to extend or implement num.
    */
    
    翻译:
    /**
    * 整数或浮点数。
    * 除[int]或[double]之外的任何类型都是编译时错误
    * 试图扩展或实现num。
    */

    也就是说它是一个数值类型,仅支持int 和 double类型。

    4.可选参数

    一个函数可以有两种参数:可选的和必需的,必需参数放在前面,后面跟可选参数

    可选参数可以是位置参数或命名参数,两种都可以有默认值,如果没有提供默认值则为null。但是这两种参数不能同时当做可选参数。

    • (1)可选的命名参数

    定义一个函数,使用 {param1, param2, …} 指定命名参数,调用函数时,你可以指定使用命名参数 paramName: value

        无默认值例子:

    /**
    * 没有默认值
    */
    void printBool({bool flag, bool action}) => print("flag: " + flag.toString() + "
    action: " + action.toString() + "
    ");

        有默认值(命名参数使用“=”指定默认值)例子:

    /**
    * 有默认值
    */
    void printDefaultBool({bool flag = false}) => print(flag);

        主函数中我们调用printBool 和 printDefaultBool函数:

    main(List<String> arguments) {
      printBool(flag: true, action: false);
      printBool(flag: false);
      printBool();
    
      printDefaultBool(flag: true);
      printDefaultBool();
    }

    控制台输出结果:

     

    (2)可选的位置参数

    把参数用 [ ] 包装起来,就能标识成位置参数

    无默认值例子:

    /**
    * 可选的位置参数
    * 无默认值
    */
    String msg(String msg, [String time]){
      if (time != null) {
        return msg + ' with ' + time;
      }
      return msg;
    }

    有默认值(位置参数使用“=”指定默认值)例子:

    /**
    * 可选的位置参数
    * 有默认值
    */
    String msgTwo(String msg, [String time = '2018', String name]){
      if (time == null) {
        return msg + " from " + name;
      }
    
      if (name != null) {
        return msg + " with " + time + " from " + name;
      }
      return msg + " with " + time;
    }

    主函数中我们调用msg 和 msgTwo函数:

    print(msg("This is msg content", '2017'));
    print(msg("Tiis is msg content"));
    
    print(msgTwo("This is msgTwo content", '2017', 'liyahong'));
    print(msgTwo("This is msgTwo content", null, 'liyahong'));
    print(msgTwo("This is msgTwo content"));

    控制台输出结果:

     

    总结:可选的命名参数的声明使用“{}”,使用“:”指定默认值,可选的位置函数的声明使用“[]”,使用“=”指定默认值。

    5.关于重载

     Dart语言是不支持方法重载( 重载就是方法名相同,参数(个数或类型)不同(称之为签名不同))的。这里可能会有人问:“Dart不支持方法重载,那构造函数怎么办呢?”,虽然Dart它不支持方法的重载,但是它支持命名构造函数,我们通过下面例子学习一下:

      class Test{
        int x;
        int y;
    
        Test(){}
    
        Test.X(int x){
         this.x = x;
        }
    
        Test.Y(int y){
         this.y = y;
        }
    
        Test.XY(int x, int y){
          this.x = x;
          this.y = y;
        }
    
        @override
        String toString() {
          if (x != null && y != null) {
            return "x: " + x.toString() + " y: " + y.toString();
          }
    
          if (x != null) {
            return "x: " + x.toString();
          }
    
          if (y != null) {
            return "y: " + y.toString();
          }
          return super.toString();
       }
    }

    我们在主函数中创建Test对象:

    main(List<String> arguments) {
      Test testX = new Test.X(1);
      print(testX.toString());
    
      Test testY = new Test.Y(2);
      print(testY.toString());
    
      Test testXY = new Test.XY(3, 4);
      print(testXY.toString());
    }

    控制台输出结果:

     

    具体内容我们后面讲解。

    6.高级函数

    /**
    * 高级函数
    * element 没有指定参数类型,默认Object任何类型
    */
    printElement(element){
      print(element);
    }

    在主函数中调用printElement函数,这里是将函数作为参数传入

    main(List<String> arguments) {
      var list = ['张三', '李四', '王麻子'];
      list.forEach(printElement);
    }

    控制台输出结果:

     

    将一个函数分配给一个变量

    main(List<String> arguments) {
      var loudify = (msg) => '${msg.toUpperCase()}';
      print(loudify('hello'));
    }

    控制台输出结果:

     

    7.作用域

    dart的作用域跟其他语言一样,直接看一个例子

    var test = true;
    
    main(List<String> arguments) {
      var test1 = true;
      myFunction(){   
    var test2 = true;
        needFunction(){       
    var test3 = true;       assert(test);       assert(test1);       assert(test2);       assert(test3);     }   } }

    8.闭包

    dart的闭包就是函数对象,其实跟JavaScript的闭包函数差不多,理论请参考JavaScript的闭包函数,这里直接写个例子

    //返回一个函数对象,功能是返回累加的数字
    Function makeAdder(num addBy) {
      return (num i) => addBy + i;
    }
    
    main(List<String> arguments) {
      //创建一个函数add2,add2返回2
      var add2 = makeAdder(2);
    
      //创建一个函数add4,add4返回4
      var add4 = makeAdder(4);
    
      //add2返回2+3
      assert(add2(3) == 5);
      //add4返回4+3
      assert(add4(3) == 7);
    }

    9.函数是否相等

    测试高阶函数、静态方法和实例方法是否相等

    //一个高阶函数
    foo() {}
    
    class SomeClass {
      //一个静态方法
      static void bar() {}
      //一个实例方法
      void baz() {}
    }
    
    main(List<String> arguments) {
      var x;
    
      //比较高阶函数
      x = foo;
      assert(foo == x);
    
      //比较静态方法
      x = SomeClass.bar;
      assert(SomeClass.bar == x);
    
      //比较实例方法
      var v = new SomeClass();
      var w = new SomeClass();
      var y = w;
      x = w.baz;
    
      assert(y.baz == x);
      assert(v.baz != w.baz);
    }
  • 相关阅读:
    Ubuntu14.04安装ROS Indigo
    STM32F103移植uCOSIII始终卡在PendSV或Systick处解决办法
    STM32F103移植uCOSIII始终卡在PendSV或Systick处解决办法
    WIN7下PS/2等键盘失灵无法使用的解决办法--实测有效
    WIN7下PS/2等键盘失灵无法使用的解决办法--实测有效
    在altium designer9 等中使用protell99se的如0805,0603等PCB封装库
    在altium designer9 等中使用protell99se的如0805,0603等PCB封装库
    VB将输入文本框的数字分割并按十六进制发送
    Windows 10同步时间的方法
    maven安装cucumber的pom文件设置
  • 原文地址:https://www.cnblogs.com/lxlx1798/p/11011663.html
Copyright © 2011-2022 走看看