• 初次翻译,部分内容并非按字面翻译,是按本人理解进行了内容重组。如有错误望指正。

Dart是完全的面向对象的语言,甚至函数也是一个Function类型的对象。这意味着函数可以赋值给变量或者作为函数的参数。你可以直接用变量名(其实现了Function类)作为函数名直接调用。

参考如下示例代码:

/*如果类实现了call方法,它可以当成Function直接调用*/
class WannabeFunction {
call(String a, String b, String c) => '$a $b $c!';
} main() {
var wf = new WannabeFunction();
var out = wf("Hi","there,","gang");
print('$out');

下面是一个函数写法的示例:

bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}

尽管Dart要求public的API需要说明返回类型,但是未明确指定返回类型的函数也是可以正常运行的

isNoble(atomicNumber) {
return _nobleGases[atomicNumber] != null;
}

For functions that contain just one expression, you can use a shorthand syntax:

如果函数体只包含一条语句的代码块,你可以用如下简略写法:

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
The => expr syntax is a shorthand for { return expr; }. The => notation is sometimes referred to as arrow syntax.

注意:必须是一条语句的代码块,可以放在=>和;之间。

函数由两种参数类型:必须和可选。一般必须参数写在前面,可选参数紧随其后。

Optional parameters 可选参数

可选参数定义方式是位置型和命名型两种二选一。

可选命名参数定义时,你可以指定参数名和参数默认值,如下所示:

enableFlags(bold: true, hidden: false);

当定义函数时,也可以用{param1, param2, …} 来描述命名参数。如下所示:

/// Sets the [bold] and [hidden] flags ...
void enableFlags({bool bold, bool hidden}) {...}

Flutter的对象初始化方法入参是复合型的,所以组件可以用命名参数的写法准确映射到各个字段。

你可以对命名参数添加@required,那么它就变为一个必须参数。

const Scrollbar({Key key, @required Widget child})
When a Scrollbar is constructed, the analyzer reports an issue when the child argument is absent.

@required在meta的包中定义,使用时,需要引入import package:meta/meta,获取其它包,其中包含了export meta的定义。

Optional positional parameters 可选位置参数

在[]中定义的参数被称为位置型参数。

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

如下是无位置型参数的函数调用

assert(say('Bob', 'Howdy') == 'Bob says Howdy');

如下是有位置型参数的函数调用。

assert(say('Bob', 'Howdy', 'smoke signal') ==
'Bob says Howdy with a smoke signal');

Default parameter values 参数默认值

你可以用=给命名参数或者位置参数赋默认值。其中,默认值必须是常量。如果参数没有定义默认值,其默认为null

下面是命名参数的默认值写法

/// Sets the [bold] and [hidden] flags ...
void enableFlags({bool bold = false, bool hidden = false}) {...}
// bold will be true; hidden will be false.
enableFlags(bold: true);

废弃特性:旧的代码默认值用:做赋值,原因是命名参数只能用:赋值,现在该支持已被删除,请使用=做参数默认值赋值

下面是位置型参数定义默认值的例子:

String say(String from, String msg,
[String device = 'carrier pigeon', String mood]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
if (mood != null) {
result = '$result (in a $mood mood)';
}
return result;
}
assert(say('Bob', 'Howdy') ==
'Bob says Howdy with a carrier pigeon');

你也可以给默认值赋值lists或者maps,下面就是这样的例子:

void doStuff(
{List<int> list = const [1, 2, 3],
Map<String, String> gifts = const {
'first': 'paper',
'second': 'cotton',
'third': 'leather'
}}) {
print('list: $list');
print('gifts: $gifts');
}

The main() function 主函数

每个应用都会有主函数,作为程序运行的入口。main函数就是Dart的主函数,它的返回值是void,入参是一个字符串数组。

void main() {
querySelector('#sample_text_id')
..text = 'Click me!'
..onClick.listen(reverseText);
}

注意:..是对象的链式调用的写法。

下面是一个带有参数的main函数:

// Run the app like this: dart args.dart 1 test
void main(List<String> arguments) {
print(arguments); assert(arguments.length == 2);
assert(int.parse(arguments[0]) == 1);
assert(arguments[1] == 'test');
}

你可以用args库来解析命令行参数。

Functions as first-class objects 函数型参数

你可以使用函数作为一个入参传递给另一个函数。如下面例子:

void printElement(int element) {
print(element);
} var list = [1, 2, 3]; // Pass printElement as a parameter.
list.forEach(printElement);

你可以函数定义为变量,如下面所示:

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

Anonymous functions 匿名函数

大部分函数都有函数名,比如main(),printElement(),你也可以定义一个无函数名的函数,可用lambda或者closure写法,我们称之为匿名函数。同时可以将匿名函数赋予一个变量来调用。匿名函数和命名函数一样,都可以有0个或者更多的入参。如下示例所示:


([[Type] param1[, …]]) {
codeBlock;
};

下面是一个具体示例:

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

如果函数体只是一个语句的代码块,你可以如下简化,去除{}.

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

Lexical scope 词汇作用域

Dart是一个lexically scoped language,意思是变量的作用域是和变量所以的代码块有关系,在变量所在代码块中,可以访问到变量。

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

Lexical closures 词汇闭包

A closure is a function object that has access to variables in its lexical scope, even when the function is used outside of its original scope.

Functions can close over variables defined in surrounding scopes. In the following example, makeAdder() captures the variable addBy. Wherever the returned function goes, it remembers addBy.

/// Returns a function that adds [addBy] to the
/// function's argument.
Function makeAdder(num addBy) {
return (num i) => addBy + i;
} void main() {
// Create a function that adds 2.
var add2 = makeAdder(2); // Create a function that adds 4.
var add4 = makeAdder(4); assert(add2(3) == 5);
assert(add4(3) == 7);
}

Testing functions for equality 测试函数的相等性

下面是函数的顶层函数,静态方法,对象方法的相等性

void foo() {} // A top-level function

class A {
static void bar() {} // A static method
void baz() {} // An instance method
} void main() {
var x; // Comparing top-level functions.
x = foo;
assert(foo == x); // Comparing static methods.
x = A.bar;
assert(A.bar == x); // Comparing instance methods.
var v = A(); // Instance #1 of A
var w = A(); // Instance #2 of A
var y = w;
x = w.baz; // These closures refer to the same instance (#2),
// so they're equal.
assert(y.baz == x); // These closures refer to different instances,
// so they're unequal.
assert(v.baz != w.baz);
}

Return values 返回值

所有函数都有返回值,如果没有特别约定,返回值为null.这是编译时,内置追加到函数体中。


foo() {} assert(foo() == null);
  • 第四篇准备翻译 Operators操作符

3.Functions-函数(Dart中文文档)的更多相关文章

  1. 1.Variables-变量(Dart中文文档)

    初次翻译,部分内容并非按字面翻译,是按本人理解进行了内容重组.如有错误望指正. 如下是变量定义和赋值的示例 var name = 'Bob'; 变量存储的是一个引用地址.如上的变量name指向了一个值 ...

  2. 2.Built-in types-基本数据类型(Dart中文文档)

    初次翻译,部分内容并非按字面翻译,是按本人理解进行了内容重组.如有错误望指正. Dart语言内置如下数据类型: numbers strings booleans lists (所谓的数组) maps ...

  3. 8.Generics 泛型(Dart中文文档)

    这篇翻译的不好 如果你看API文档中的数组篇,你会发现类型一般写成List.<...>的写法表示通用类型的数组(未明确指定数组中的数据类型).通常情况泛型类型用E,T,S,K,V表示. W ...

  4. 7.Classes-类(Dart中文文档)

    Dart是一个面向对象的语言,同时增加了混入(mixin)继承的特性.对象都是由类初始化生成的,所有的类都由Object对象继承.混入继承意味着尽管所有类(除了Object类)只有一个父类,但是类的代 ...

  5. 6.Exceptions-异常(Dart中文文档)

    异常是用于标识程序发生未知异常.如果异常没有被捕获,If the exception isn't caught, the isolate that raised the exception is su ...

  6. 5.Control flow statements-流程控制(Dart中文文档)

    你可以使用如下流程控制符: if and else for loops while and do-while loops break and continue switch and case asse ...

  7. 4.Operators-操作符(Dart中文文档)

    Dart有如下操作符: Description Operator unary postfix expr++ expr-- () [] . ?. unary prefix -expr !expr ~ex ...

  8. Flutter 中文文档网站 flutter.cn 正式发布!

    在通常的对 Flutter 介绍中,最耳熟能详的是下面四个特点: 精美 (Beautiful):充分的赋予和发挥设计师的创造力和想象力,让你真正掌控屏幕上的每一个像素. ** 极速 (Fast)**: ...

  9. 学习JQuery中文文档之get()函数

    前端大神群的群主告诉我们:学习一个框架最好的方法是去把官方文档研究一遍. 现在正式开始我的前端之路,从JQuery的中文文档开始. 基础不牢固,看起来有点慢,但是我会一直坚持下去的.把遇到的问题都记录 ...

随机推荐

  1. mysql 运行 sql 脚本

    方式一: 打开脚本,复制里面的全部内容,登陆数据库后运行. 方式二: window cmd 运行如下命令: mysql -u root -proot --port 3306 <D:\simple ...

  2. Pig UDF 用户自定义函数

    注册UDF do.pig的内容如下: register /xx/yy.jar data = load 'data'; result = foreach data generate aa.bb.Uppe ...

  3. 机器学习数学知识中令人费解的notation符号注解

    $argmin_xf(x), min(f(x))$ $min(f(x))$的意思是函数$f(x)$的最小值 $argmin$的意思是返回使得表达式取得最小值时对应的输入变量值.例如$argmin_xf ...

  4. 干货:如何使用N点虚拟管理系统?

    N点虚拟主机管理系统怎么用呢?最近有许多朋友问我关于这款虚拟主机管理系统如何使用?在讲如何使用N点虚拟主机管理系统之前,我们先来了解一下N点虚拟主机管理系统的介绍. ​      N点虚拟主机管理系统 ...

  5. [翻译] Icon and Image Sizes

    Icon and Image Sizes iOS Human Interface Guidelines Every app needs an app icon and a launch file or ...

  6. [翻译] iOSSharedViewTransition

    iOSSharedViewTransition iOS 7 based transition library for View Controllers having a Common View 基于i ...

  7. Linux学习---Linux用户审计简单版

    [root@localhost root]# vim /etc/profile # SHENJI history USER=`whoami` USER_IP=`who -u am i 2>/de ...

  8. CDN高级技术专家周哲:深度剖析短视频分发过程中的用户体验优化技术点

    深圳云栖大会已经圆满落幕,在3月29日飞天技术汇-弹性计算.网络和CDN专场中,阿里云CDN高级技术专家周哲为我们带来了<海量短视频极速分发>的主题分享,带领我们从视频内容采集.上传.存储 ...

  9. libc.so.6: cannot open shared object file: No such file or diretory

    环境 centos6.6. 由于误操作 删除了 rm -f /lib64/libc.so.6 导致其他命令不能使用 解决方法: /sbin/sln /lib64/libc-

  10. HDFS下载数据机制的底层分析

    HDFS下载数据机制的底层分析 Hadoop中的RPC(Remote Procedure Call)框架 hadoop中结点间的通信采用的是RPC. RPC框架的实现机制图解: 从hdfs下载数据的源 ...