【Flutter 1-9】Flutter教程Dart语言——函数和匿名函数

作者 | 弗拉德
来源 | 弗拉德(公众号:fulade_me)

函数

Dart 同样也是一种面向对象的语音。所以即便函数也是一个对象。类型为 Function,这意味着函数可做作为变量,也也可以作为函数的参数。

下面是定义一个函数的例子:

isEmpty(List aList) {
  return aList.length == 0;
}

为了规范其实我们需要在函数的头部声明一下返回值类型,当然如果不声明也可以运行,

bool isEmpty(List aList) {
  return aList.length == 0;
}

如果函数体内只包含一个表达式,你可以使用简写语法:

bool isEmpty(List aList) => aList.length == 0;

=> 表达的 是 { return 表达式; } 的简写,有时=>也称之为胖箭头语法

参数

函数可以有两种形式的参数:必选参数可选参数。必选参数定义在参数列表前面,可选参数一定是定义在必要参数后面。

可选的命名参数

当你调用函数时,可以使用 参数名: 参数值 的形式来指定命名参数。例如:

enableFlags(bold: true, hidden: false);

已命名的参数是可选参数了,除非他们被特别标记为 required

定义函数时,使用 {param1, param2, …} 来指定命名参数:

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

虽然命名参数是可选参数的一种类型,但是你仍然可以使用 @required 注解来标识一个命名参数是必须的参数,此时调用者则必须为该参数提供一个值。例如:

const Scrollbar({Key key, @required Widget child})

如果调用者想要通过 Scrollbar 的构造函数构造一个 Scrollbar 对象而不提供 child 参数,则会导致编译错误。

可选参数

使用 [] 将一系列参数包裹起来作为可选参数:

strings(String s1, String s2, [String s3]) {
  var result = '$s1 and $s2';
  if (s3 != null) {
    result = '$result and $s3';
  }
  print(result);
}

下面是不使用可选参数调用上述函数的示例:

strings("s1", "s2");
s1 and s2

下面是使用可选参数调用上述函数的示例:

strings("s1", "s2", "s3");
s1 and s2 and s3
默认参数值

我们可以用 = 为函数的命名参数和可选参数定义默认值,默认值必须为编译时常量,没有指定默认值的情况下默认值为 null

下面是设置可选参数默认值示例:

/// 设置 [bold] 和 [hidden] 标识……
void enableFlags({bool bold = false, bool hidden = false}) {...}

// bold 的值将为 true;而 hidden 将为 false。
enableFlags(bold: true);

下一个示例 默认值:

strings(String s1, String s2, [String s3 = 'this is s3', String s4]) {
  var result = '$s1 and $s2';
  if (s3 != null) {
    result = '$result and $s3';
  }
  if (s4 != null) {
    result = '$result and $s4';
  }
  print(result);
}

strings("s1", "s2");
s1 and s2 and this is s3
main() 函数

每个 Dart 程序都必须有一个 main() 顶级函数作为程序的入口,main() 函数返回值为 void

下面是一个 Flutter 应用的 main() 函数示例:

void main() {
  runApp(MyApp());
}
函数作为参数

可以将函数作为参数传递给另一个函数。例如:

void printElement(int element) {
  print(element);
}
// 将 printElement 函数作为参数传递。
var list = [1, 2, 3];
list.forEach(printElement);

你也可以将函数赋值给一个变量,比如:

var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
var result = loudify('hello');
print(result);

匿名函数

大多数方法都是有名字的,比如 main()printElement()。你可以创建一个没有名字的方法,称之为 匿名函数,其实匿名函数很常见,也有不同的叫法,在C++里面叫Lambda表达式,在Objective-C叫Block闭包。你可以将匿名方法赋值给一个变量然后使用它。

匿名方法看起来与命名函数h类似,在括号之间可以定义参数,参数之间用逗号分割。

后面大括号中的内容则为函数体:

([[类型] 参数[, …]]) {
  函数体;
};

下面代码定义了只有一个参数 item 且没有参数类型的匿名方法。List 中的每个元素都会调用这个函数,打印元素位置和值的字符串:

var list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
  print('${list.indexOf(item)}: $item');
});

如果函数体内只有一行语句,你可以使用胖箭头缩写法。下面代码的运行结果,与上面代码的运行结果是一致的。

list.forEach(
    (item) => print('${list.indexOf(item)}: $item'));

变量作用域

变量的作用域在写代码的时候就确定了,大括号内定义的变量只能在大括号内访问,与 Java 类似。

下面是一个嵌套函数中变量在多个作用域中的示例:

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);
    }
  }
}

注意 nestedFunction() 函数可以访问包括顶层变量在内的所有的变量。

返回值
所有的函数都有返回值。没有显示返回语句的函数最后一行默认为执行 return null;。

foo() {}

assert(foo() == null);

本文所有代码都已上传到Github

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

推荐阅读更多精彩内容