Dart基础(四)-函数

简介:

Dart是一种真正的面向对象语言,所以函数也是对象,并且有一个类型Function。这意味着函数可以赋值给变量,也可以作为参数传递给其他函数。您还可以调用Dart类的实例,就像它是一个函数一样。有关详细信息,请参见Callable类。

  要点总结:

  • 函数也是对象,且函数有对应的类Function;
  • 函数可以作为变量,也可作为函数的参数;
  • 类的实例也可以像函数一样调用,见可调用类;

函数的声明和实现:

  函数实现:

returnType functionName(param1, param12, ...) {
 code
 return type;
}

一些注意点:

  • 返回类型可以省略,但是为了可读性一般不会省略;
  • 当返回类型为void时,reutrn语句为return null;可以省略;
  • 箭头语法=> expr{return expr;}的省略写法,且=>;之间只有表达式不能出现语句;
// 例子
bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

// 省略返回值
isNoble(atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

// 箭头语法
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

函数参数:

一个函数可以有任意数量的所需位置参数。后面可以跟命名参数,也可以跟可选的位置参数(但不能同时跟)。

  参数分类

类别 中文 描述
No Named parameters 匿名参数 调用函数时不用参数的名字
Named parameters 命名参数 {} 内,调用函数时需要参数的名字
Optional Named parameters 可选命名命名参数 调用函数时该参数不是必传参数
required parameters 必传参数 调用函数时必传该参数
Optional positional parameters 可选位置参数 应用程序的入口

注意点:

  • {}内必传参数需要加required关键字;
  • {}内可选不为空的参数,必须提供默认值;
  • {}内可选为空的参数,需要?允许参数为null;
  • []内可选位置参数,基本上没用。
// 匿名必传参数
void showName(String name) {
  print(name);
}
// 调用
showName("Luck");

// 命名参数:name为命名必传参数;age和sex是可选命名参数,不能为空,需提供默认值;hadCar是可选默认参数,可以为null
void show({ required String name, int age = 0, bool sex = true, bool? hadCar}) {
  print('name = $name, age = $age, sex = ${sex ? 'man' : 'woman'}');
  if (hadCar == true) {
    print('$name had car');
  }
}
// 调用
show(name: "Lucy", age: 12, sex: true, hadCar: true);

函数分类:

  函数分类:

类别 中文 描述
main() 主函数或者入口函数 应用程序的入口
Global function 全局函数 main之外定义的函数,或是直接在main函数中定义的函数都是全局函数,可以可以全局调用
Local function 局部函数 相对全局函数定义,不是全局函数的,都是局部函数
instance function 实例函数 类实例调用的函数
class/static function 类函数或者静态函数 类名直接调用的函数
Anonymous function 匿名函数 没有名字的函数,也被称为(java中)lambda 或者 (swift中)closure 闭包

main()函数:

每个应用程序都必须有一个顶级的main()函数,它作为应用程序的入口点。main()函数返回void,并有一个可选的List<String>参数作为参数。

// main之外定义的全局函数
int globalOutMain() {
    return 123;
}

void main(){
    // main里的全局函数
    int globalInMain(){
        return 123;
    }
    // 调用
    globalOutMain();
    globalInMain();
}

// 实例方法和类方法
class Person {
  static String className = 'Person';
  late final String name;
  
  void show() {
    print(name);
  }
  
  static void showClassName() {
    print(className);
  }
}
    // 调用
    final persion = Person();
    persion.name = 'jack';
    persion.age = 16;
    persion.show();
    Person.showClassName();
匿名函数 :

匿名函数的声明:

// 第一种声明
(param1, param2, ...) { 
  code; 
  return type;
}
// 第二种声明:声明一个匿名函数,并赋值给变量functionName
functionName(param1, param2, ...) { 
  code; 
  return type;
}
// 第二种声明等价于
var functionName = (param1, param2, ...) { 
  code; 
  return type;
};

注意点:

  • 匿名函数可以赋值给变量;
  • 其实匿名函数可以有名字的,即为赋值的变量;
  • 匿名函数通过赋值的变量进行调用,这就是所说的函数表达式;
  • 匿名函数可以自执行;
  • 匿名函数哦一些方法的回调函数,即匿名函数可以作为函数的参数。
    // 声明一个匿名函数,并赋值给变量function1
    function1(int a, int b) {
      return (a + b);
    }
    // 将匿名函数赋值给一个变量
    var fVar = function1;
    // 匿名函数调用
    print(function1(2, 3));
    print(fVar(2, 3));
    // 匿名函数自执行
    () {
      print('匿名函数自执行');
    } ();
    const list = ['apples', 'bananas', 'oranges'];
    // 匿名函数作为回调函数,即作为函数的参数
    list.forEach((item) {
      print('${list.indexOf(item)}: $item');
    });

变量作用域和变量闭包:

  Dart是一种词法作用域限定的语言,这意味着变量的范围是静态地确定的,简单地由代码的布局决定。
  闭包即匿名函数是一个函数对象,它可以访问其词法作用域内的变量,即使该函数是在其原始作用域之外使用的。

  • {}外的变量或常量可以在{}内使用;
  • {}内的变量或常量不可以在{}外使用;
bool topLevel = true;

void main() {
  var insideMain = true;

  void myFunction() {
    var insideFunction = true;

    void nestedFunction() {
      var insideNestedFunction = true;

      assert(topLevel);
      assert(insideMain);
      assert(insideFunction);
      assert(insideNestedFunction);
    }
  }
}

// 返回值是闭包函数
Function makeAdder(int addBy) {
  return (int i) => addBy + i;
}
    // 调用
    var add2 = makeAdder(2);
    var add4 = makeAdder(4);
    print(add2(1));
    print(add4(1));
函数等价判断 :

下面是一个测试顶级函数(全局函数)、静态方法和实例方法是否相等的例子:

可调用类:

  可调用类即类的实例可以像函数一样进行调用的类。怎样才能让类的实例像函数一样进行调用呢?很简单只需要在类中实现一个call()函数。如下:

class WannabeFunction {
  // String call(String a, String b, String c) => '$a $b $c!';
  // String call() => '123';
  int call(int a) => (a + 1);
}

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

推荐阅读更多精彩内容