Dart语言基础之函数

原文:https://www.dartlang.org/guides/language/language-tour
Dart是一个真`面向对象语言。所以甚至方法也是对象并且它的类型是Function。这就说明,方法可以被分配给一个变量或者作为参数传递给其他方法。你也可以调用一个Dart类(class)如果它是一个方法。see Callable classes.

实现一个函数:

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

虽然 Effective Dart 建议 type annotations for public APIs, 函数省略返回值仍能工作:

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.

一个方法有两种类型的参数:必须的和可选的。必须的参数放在参数列表前面,后面跟着可选参数。命名可选参数可以用@Required来标记。

可选参数

可选参数可以是按位的也可以是命名的,但不能两者兼备。

可选命名参数

当你调用一个函数,你可以指定命名参数paramName: value.

enableFlags(bold: true, hidden: false);

当你定义一个函数,用{param1, param2, …}来指定命名参数。

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

你可以用@Require注解命名参数

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

可选位置参数

[...]来括住的参数是位置可选参数:

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

默认参数值

你的函数可以用=来为命名参数和位置参数指定默认值,默认值必须是编译时常量。如果没有提供默认值,默认值为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');

你也可以把list或map作为参数值.

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

把函数作为 first-class 对象

你可以把函数作为参数传给另一个函数:

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 !!!');

匿名函数

大多数情况下函数是命名的,你也可以定义匿名函数,有时称作lambda或者闭包。你可以将一个匿名函数赋值给一个变量,如此,你可以将它加入一个集合或者从集合中删除。

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

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

词法作用域

Dart是一种词法作用域类型的语言,意思是变量的作用域是静态的,简单的说是由代码布局决定的。

Here is an example of nested functions with variables at each scope level:

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

Notice how nestedFunction() can use variables from every level, all the way up to the top level.

~Lexical闭包

闭包是一个函数对象,它可以访问其词法范围中的变量,即使该函数在其原始范围之外使用也是如此。--来自Google翻译

函数可以关闭周围范围中定义的变量。 在以下示例中,makeAdder()捕获变量addBy。 无论返回的函数在哪里,它都会记住addBy。--来自Google翻译。

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

测试函数是否相等

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 null; 语句会默认加入到函数结尾

foo()  {}  assert(foo()  ==  null);

你可能感兴趣的:(Dart语言基础之函数)