Dart入門词裤?一篇文章就夠了!

近期公司準(zhǔn)備啟動(dòng)新項(xiàng)目鳖宾,經(jīng)過技術(shù)團(tuán)隊(duì)一番調(diào)研吼砂,決定采用 Flutter 來開發(fā)第一版App,故作此文鼎文,常來回顧溫習(xí)渔肩。由于項(xiàng)目采用敏捷開發(fā)模式,故本文主要總結(jié)和記錄 Dart 常用語法拇惋,更多高級(jí)和生僻用法將在后面開發(fā)過程中不定期更新赖瞒。

First of all

在我們正式接觸 Dart 語法之前女揭,需要銘記以下內(nèi)容,這將會(huì)對(duì)后續(xù) Dart 語法的學(xué)習(xí)栏饮、理解和應(yīng)用有很大幫助:

  • 萬物皆對(duì)象吧兔, 每個(gè)對(duì)象都是一個(gè)類的實(shí)例。在 Dart 中袍嬉,甚至連數(shù)字境蔼、方法和 null 都是對(duì)象,并且所有的對(duì)象都繼承于 Object 類伺通。
  • 盡管 Dart 語言是一種強(qiáng)類型語言箍土,但你在類型聲明時(shí)仍然可以不指定類型,因?yàn)?Dart 可以自動(dòng)進(jìn)行類型推斷罐监。如在代碼 var number = 5; 中吴藻,number 變量的類型就被推斷為 int,當(dāng)你并不想顯式地聲明類型時(shí)弓柱,你可以使用特有的類型 dynamic 來標(biāo)識(shí)沟堡。
  • Dart 語言同樣支持泛型,如 List<int>矢空、List<dynamic>(同 Java 中的 List<Object>)航罗。
  • Dart 語言支持頂級(jí)方法(即不與類綁定的方法,如上的 main 方法)屁药,以及綁定類和實(shí)例的方法(分別對(duì)應(yīng)靜態(tài)方法和實(shí)例方法)粥血,而且還支持方法嵌套(同 Python 和 JS)。
  • 同樣酿箭,Dart 還支持頂級(jí)變量复亏,以及在類中定義的變量(如靜態(tài)變量和實(shí)例變量)。
  • 和 Java 不同的是缭嫡,Dart 沒有 public蜓耻、 protected 以及 private 關(guān)鍵字。它通過給變量或者方法名加上 _ 前綴來將其標(biāo)識(shí)為私有域械巡。

變量

你可以通過 var 或者特定的類型來修飾變量刹淌,如果變量的類型不是固定的,也可以通過 dynamic 或者 Object 來修飾讥耗。如:

// 類型推斷
var name = 'Bob';
// 指定類型
String name = 'Bob';
// 類型不局限于string
dynamic name = 'Bob';

默認(rèn)值

Dart 中聲明時(shí)如果未初始化有勾,會(huì)被自動(dòng)初始化為null

int lineCount;
assert(lineCount == null);

注:assert 只在開發(fā)環(huán)境有效,在實(shí)際的生產(chǎn)環(huán)境無效古程。

final 與 const

finalconst 標(biāo)識(shí)該變量只能被賦值一次蔼卡,區(qū)別在于 final 是運(yùn)行時(shí)賦值,const 是編譯時(shí)賦值挣磨。

final String nickname = 'Jack';
// final修飾時(shí), 可省略類型聲明
final name = 'Jack';

const不僅可以用來聲明變量雇逞,還能用來創(chuàng)建常量值荤懂,如:

// 此時(shí)不能在對(duì)列表a進(jìn)行更新操作
var a = const [1, 2];
// 注意以下 const 修飾的區(qū)別
var foo = const [];
const baz = []; // Equivalent to `const []`
...
foo = [1, 2, 3]; // Was const []
baz = [42]; // Error: Constant variables can't be assigned a value.

數(shù)據(jù)類型

Dart 語言支持的數(shù)據(jù)類型與 Java 類似,但也有所不同塘砸,下面我們來按照“求同存異”的法則來分別認(rèn)識(shí)它們节仿。

數(shù)字類型

Dart 中的數(shù)字類型只有兩種:Intdouble。與 Java 不同的是掉蔬,它并沒有提供 float 類型廊宪。例如,我們可以通過以下方式來定義數(shù)字:

// 定義整型
var x = 123;
var hex = 0xDEADBEEF;
// 定義雙精度類型
var y = 1.199;
var exponents = 1.42e5;

再來看下常用的數(shù)據(jù)轉(zhuǎn)換該如何執(zhí)行:

// String -> int
var a = int.parse('1');
assert(a == 1);

// String -> double
var b = double.parse('1.1');
assert(b == 1.1);

// int -> String
String c = 1.toString();
assert(c == '1');

// double -> String
String d = 3.14159.toStringAsFixed(2);
assert(d == '3.14');

int 類型可以執(zhí)行傳統(tǒng)的按位移位( <<女轿,>> )箭启,AND( & )和OR( | )運(yùn)算符,如:

assert((3 << 1) == 6); // 0011 << 1 == 0110
assert((3 >> 1) == 1); // 0011 >> 1 == 0001
assert((3 | 4) == 7);  // 0011 | 0100 == 0111

字符串類型

字符串的聲明可以通過單引號(hào)或者雙引號(hào)來引入:

var s1 = 'Single quotes work well for string literals.';
var s2 = "Double quotes work just as well.";
var s3 = 'It\'s easy to escape the string delimiter.';
var s4 = "It's even easier to use the other delimiter.";

字符串拼接可以通過 + 或者 換行 來實(shí)現(xiàn)蛉迹,如:

var a = '123' + '456'
var b = '123'
    '456';
assert(a == b)
print(a);
// Out: 123456

另外傅寡,可以通過三重引號(hào)來修飾多行字符串(維持特定格式):

var s1 = '''
You can create
multi-line strings like this one.
''';

var s2 = """This is also a
multi-line string.""";

布爾類型

Dart 中的 bool 類型可以通過 if-else 或者是 assert 來檢查,如:

// Check for an empty string.
var fullName = '';
assert(fullName.isEmpty);

// Check for zero.
var hitPoints = 0;
assert(hitPoints <= 0);

// Check for null.
var unicorn;
assert(unicorn == null);

// Check for NaN.
var iMeantToDoThis = 0 / 0;
assert(iMeantToDoThis.isNaN);

數(shù)組類型

在 Dart 語言中北救,數(shù)組即列表荐操,列表即數(shù)組。

void main() {
  var list = [1, 2, 3];
  list.add(4);
  list.remove(3);
  list[1] = 5;
  var last = list[list.length - 1];
  print('list is $list');
  print('last is $last');
}

另外扭倾,你可以通過 或者 ...?(避免空異常) 來批量插入多個(gè)元素:

var list1 = [1, 2, 3];
var list2 = [0, ...list1];

var list3;
var list24 = [0, ...?list3];

除此以外,還可以通過 if 或者 for 條件運(yùn)算符來插入元素:

var nav = [
  'Home',
  'Furniture',
  'Plants',
  if (promoActive) 'Outlet'
];

var listOfInts = [1, 2, 3];
var listOfStrings = [
  '#0',
  for (var i in listOfInts) '#$i'
];
assert(listOfStrings[1] == '#1');

Set 和 Map

Dart中的Set是無序的唯一項(xiàng)的集合挽绩。要?jiǎng)?chuàng)建一個(gè)空集合膛壹,有以下兩種方式:

var names = <String>{};
Set<String> names = {}; // This works, too.
// var names = {}; // Creates a map, not a set.

通過以下方式創(chuàng)建常量 Set:

final constantSet = const {
  'fluorine',
  'chlorine',
  'bromine',
  'iodine',
  'astatine',
};
// constantSet.add('helium'); // Uncommenting this causes an error.

至于 Map 存儲(chǔ)的是鍵值對(duì)數(shù)據(jù),keyvalue 可以是任何類型唉堪∧A可以通過以下方式創(chuàng)建一個(gè) Map:

var gifts = Map();
gifts['first'] = 'partridge';
gifts['second'] = 'turtledoves';
gifts['fifth'] = 'golden rings';

// 或者通過以下方式
var gifts = {
  // Key:    Value
  'first': 'partridge',
  'second': 'turtledoves',
  'fifth': 'golden rings'
};

函數(shù)

Dart 是一門完全面向?qū)ο蟮恼Z言,即使它的函數(shù)也是一個(gè)對(duì)象唠亚,并且有自己的類型—— Function链方。這就意味著函數(shù)可以被賦值為一個(gè)變量,或者作為一個(gè)參數(shù)在其他函數(shù)之間傳遞灶搜。

對(duì)于只包含一個(gè)表達(dá)式的方法體祟蚀,你也可以使用 => 的簡寫形式,如:

void say() {
    print('123');
}

// 該寫法與以上有同樣效果
void say2() => print('123');

此外割卖,函數(shù)同樣支持類型推斷前酿,如:

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

// 與下面的效果一樣
isNoble(atomicNumber) => _nobleGases[atomicNumber] != null;

可選參數(shù)

與 kotlin 語言類似,Dart 的 函數(shù)同樣支持可選參數(shù)這一功能鹏溯,主要分為命名可選參數(shù)位置可選參數(shù)罢维,它們不能在一個(gè)函數(shù)中同時(shí)使用。但它們都支持默認(rèn)參數(shù)設(shè)置丙挽。

  • 命名可選參數(shù)

    命名可選參數(shù)通過花括號(hào) {} 來指定可選的命名參數(shù)肺孵,如:

    void main() {
      hello(name: 'Tom');
    }
    
    void hello({@required String name='Jack', int age=18}) {
      print('Hello, my name is $name, i\'m $age years old.');
    }
    

    我們可以為命名可選參數(shù)設(shè)置默認(rèn)值匀借,在使用的時(shí)候如果不指定該可選參數(shù)的值,那么它就會(huì)自動(dòng)使用默認(rèn)值平窘。另外吓肋,我們可以通過 @required 來標(biāo)注那些不想被忽略的參數(shù)。

  • 位置可選參數(shù)

    顧名思義初婆,可選位置參數(shù)就允許我們?cè)谑褂媚硞€(gè)函數(shù)時(shí)可以忽略某個(gè)參數(shù)蓬坡,如:

    void main() {
      sayHello('Tom', 19);
    }
    
    void sayHello(String name, int age, [String hobby = null]) {
      var result = 'Hello, my name is $name, i\'m $age years old';
      if (hobby != null) {
          result += ', my bobby is $hobby.';
      }
      print(result);
    }
    

匿名函數(shù)

不管什么語言,好像都能看到匿名函數(shù)的身影磅叛,我們可以通過以下方式來簡單聲明一個(gè)匿名函數(shù):

var loge = (msg) => Logger.print(Logger.Error, msg);

void main() {
  loge("there has some errors");
}

Dart 中 list 就提供了匿名函數(shù) —— forEach屑咳,如:

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

常用操作符

Dart 提供了很多功能強(qiáng)大的操作符,這里列舉幾個(gè)常用的:

  • 類型判斷

    如:is 相當(dāng)于 Java 中的 instanceof

  • 整除

    如:a ~/ b 等價(jià)于 (a /b) as int

  • 非空調(diào)用

    如:a?.b 相當(dāng)于 a == null ? null : a.b

  • 三目運(yùn)算

    如:a??b 相當(dāng)于 a == null ? b : a

  • 三目賦值運(yùn)算

    如:a ??= b 相當(dāng)于 a = a == null ? b : a

  • 類型轉(zhuǎn)換

    如:a as int 相當(dāng)于 Java 中的 (int) a

  • 級(jí)聯(lián)操作符

    級(jí)聯(lián)操作符用.. 來表示弊琴,主要用來對(duì)一個(gè)對(duì)象進(jìn)行連續(xù)操作兆龙,有點(diǎn)類似 kotlin 中的 apply 和 let,如:

    var button = Button(this);
    button.text = 'Confirm';
    button.color = Color.parse("#f3f355");
    button.onClick.listen((v) => toast('Confirmed'));
    
    // 等價(jià)于下面寫法
    Button(this) 
      ..text = 'Confirm' // Use its members.
      ..color = Color.parse("#f3f355")
      ..onClick.listen((v) => toast('Confirmed'));
    

異常處理

拋異常

在 Dart 中可以拋出非空對(duì)象(不僅僅是 ExceptionError)作為異常敲董。拋出異常的方式很簡單紫皇,只需要這樣:

throw FormatException('Expected at least 1 section');

throw 'Out of llamas!';

void distanceTo(Point other) => throw UnimplementedError();

捕獲異常

我們可以通過 try-on 來捕獲某個(gè)特定異常,如:

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  buyMoreLlamas();
}

當(dāng)然腋寨,你可以拋出多個(gè)類型的 Exception聪铺,但是由第一個(gè) catch 到的分句來處理
如果 catch 分句沒有指定類型,那么它可以處理任何類型的異常:

try {
      throw 'This a Exception!';
  } on Exception catch(e) {
    print('Unknown exception: $e');
  } catch(e) {
    print('Unknown type: $e');
  }

無論是否發(fā)生異常萄窜,如果想要執(zhí)行某段代碼铃剔,可以通過 finally 實(shí)現(xiàn):

try {
      throw 'This a Exception!';
  } catch(e) {  // 如果去掉 catch 語句,那么異常將會(huì)在finally代碼塊之后傳遞查刻。
    print('Catch Exception: $e');
  } finally {
    print('Close');
  }

類和對(duì)象

Dart 中键兜,所有的對(duì)象都是類的實(shí)例,并且所有的類都是 Object 的子類穗泵。

類的定義和構(gòu)造函數(shù)

類的定義用 class 關(guān)鍵字普气,如果未顯式定義構(gòu)造函數(shù),會(huì)默認(rèn)一個(gè)空的構(gòu)造函數(shù)佃延,這一點(diǎn)與 Java 不謀而合现诀。另外,Dart 還提供 命名構(gòu)造函數(shù)這一功能履肃,格式為:Class.costructorName(var params)赶盔。這種用法在某些場景下很實(shí)用,比如:

class Person{
  String name;
  int age;
  bool sex;
  String hobby;

  Person(this.name, this.age, this.sex, this.hobby);

  /// 命名構(gòu)造函數(shù)
  Person.fromJson(Map json){
    print("Person constructor...");
    this.name  = json['name'];
    this.age   = json['age'];
    this.sex   = json['sex'];
    this.hobby = json['hobby'];
  }
}

通過命名構(gòu)造函數(shù)榆浓,我就可以直接通過多種方式來生成當(dāng)前類的實(shí)例于未,這里通過 Json 格式數(shù)據(jù)生成 Person 對(duì)象。另外,如果構(gòu)造函數(shù)只是簡單的參數(shù)傳遞烘浦,也可以直接在構(gòu)造函數(shù)后加 : 來對(duì)參數(shù)進(jìn)行賦值抖坪,多個(gè)參數(shù)可通過 , 相連:

class Point {
    num x;
    num y;
    num z;
    
    Point(this.x, this.y, z) { //第一個(gè)值傳遞給this.x,第二個(gè)值傳遞給this.y
            this.z = z;
    }
    
    Point.fromeList(var list): //命名構(gòu)造函數(shù)闷叉,格式為Class.name(var param)
            x = list[0], y = list[1], z = list[2]{//使用冒號(hào)初始化變量
    }

    //當(dāng)然擦俐,上面句你也可以簡寫為:
    //Point.fromeList(var list): this(list[0], list[1], list[2]);

     String toString() => 'x:$x  y:$y  z:$z';
}

如果你要?jiǎng)?chuàng)建一個(gè)不可變的對(duì)象,你可以定義編譯時(shí)常量對(duì)象
需要在構(gòu)造函數(shù)前加 const

class ImmutablePoint {
    final num x;
    final num y;
    const ImmutablePoint(this.x, this.y); // 常量構(gòu)造函數(shù)
    static final ImmutablePoint origin = const ImmutablePoint(0, 0); // 創(chuàng)建一個(gè)常量對(duì)象不能用new握侧,要用const
}

屬性訪問器

即我們常說的 Setter/Getter蚯瞧,主要是用來讀寫一個(gè)屬性的方法。每個(gè)字段都對(duì)應(yīng)一個(gè)隱式的 GetterSetter品擎,但是調(diào)用的時(shí)候是 obj.name埋合,而不是 obj.name()。當(dāng)然萄传,你可以通過 getset 關(guān)鍵字?jǐn)U展功能
來實(shí)現(xiàn)自己的 Setter/Getter 甚颂, 如果字段為 final 或者 const 的話,那么它只能有一個(gè) getter 方法秀菱。如:

class Rectangle {
  num left, top, width, height;

  Rectangle(this.left, this.top, this.width, this.height);

  // Define two calculated properties: right and bottom.
  num get right => left + width;
  set right(num value) => left = value - width;
  num get bottom => top + height;
  set bottom(num value) => top = value - height;
}

void main() {
  var rect = Rectangle(3, 4, 20, 15);
  assert(rect.left == 3);
  rect.right = 12;
  assert(rect.left == -8);
}

工廠構(gòu)造函數(shù)

并不是任何時(shí)候我們都需要?jiǎng)?chuàng)建一個(gè)新的對(duì)象振诬,如:可以返回一個(gè)已經(jīng)緩存好的對(duì)象或者該類的子類對(duì)象。我們以返回該類的一個(gè)緩存對(duì)象為例:

class Logger {
  final String name;
  bool mute = false;

  // _cache is library-private, thanks to
  // the _ in front of its name.
  static final Map<String, Logger> _cache =
      <String, Logger>{};

  factory Logger(String name) {
    return _cache.putIfAbsent(
        name, () => Logger._internal(name));
  }

  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) print(msg);
  }
}

注意:factory 構(gòu)造函數(shù)不能通過 this 關(guān)鍵字來獲取類的成員衍菱。

抽象類

Dart 中并沒有 interface 關(guān)鍵字赶么,只有 abstract 來修飾"抽象類",但是脊串,這里的抽象類既可以被繼承(extends)辫呻,也可以被實(shí)現(xiàn)(implements)。如:

abstract class Person {  // 可以不用 abstract 修飾洪规,如果加上 abstract 的話 Person 不能被實(shí)例化 
    String greet(who);   
}

class Student implements Person { 
    String name; 
    Student(this.name); 
     
    String greet(who) => 'Student: I am $name!'; 
} 

class Teacher implements Person { 
    String name; 
    Teacher(this.name); 
   
    String greet(who) => 'Teacher: I am $name!'; 
} 

void main() { 
    Person student = new Student('Wang'); 
    Person teacher = new Teacher('Lee'); 
    
    print( student.greet('Chen')); 
    print(teacher.greet('Chen')); 
}

同樣地印屁,Dart 中的類是單繼承循捺,多實(shí)現(xiàn)斩例。這里使用的 implements 后,子類 Student 無法去訪問父類 Persion 中的變量从橘,但是抽象方法必須顯式實(shí)現(xiàn)念赶。相反,如果使用 extends 繼承恰力,子類就可以直接使用父類的非私有變量叉谜,倘若父類不是抽象類,那么子類同樣不需要顯式實(shí)現(xiàn)里面方法踩萎。如:

// A person. The implicit interface contains greet().
class Person {
  // In the interface, but visible only in this library.
  final _name;

  // Not in the interface, since this is a constructor.
  Person(this._name);

  // In the interface.
  String greet(String who) => 'Hello, $who. I am $_name.';
}

// An implementation of the Person interface.
class Impostor implements Person {
  get _name => '';

  String greet(String who) => 'Hi $who. Do you know who I am?';
}

String greetBob(Person person) => person.greet('Bob');

void main() {
  print(greetBob(Person('Kathy')));
  print(greetBob(Impostor()));
}

運(yùn)算符重載

以下的運(yùn)算符支持重載功能:

| < | + | | | [] |
| ---- | ---- | ---- | ----- |
| > | / | ^ | []= |
| <= | ~/ | & | ~ |
| >= | * | << | == |
| | % | >> | |

這一點(diǎn)與 kotlin 語言中的運(yùn)算符重載功能類似停局。我們以下面這個(gè)表示平面向量的類為例,為它增加兩個(gè)向量相加和相減功能:

class Vector {
  final int x, y;

  Vector(this.x, this.y);

  Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
  Vector operator -(Vector v) => Vector(x - v.x, y - v.y);

  // Operator == and hashCode not shown. For details, see note below.
  // ···
}

void main() {
  final v = Vector(2, 3);
  final w = Vector(2, 2);

  assert(v + w == Vector(4, 5));
  assert(v - w == Vector(0, 1));
}

枚舉

枚舉的使用比較簡單,和 Java 中的用法類似董栽,聲明的元素 index 值從 0 開始計(jì)算码倦。

enum Color { red, green, blue }
......
assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);

Mixin 混合模式

Mixins 是一種在多個(gè)類的層級(jí)中復(fù)用類中代碼的一種方式。在類名后添加 with 關(guān)鍵字锭碳,并在 with 后緊跟類的標(biāo)識(shí)符列表袁稽,通過逗號(hào)分隔,如:

class Maestro extends Person
    with Musical, Aggressive, Demented {
  Maestro(String maestroName) {
    name = maestroName;
    canConduct = true;
  }
}

如果想要聲明一個(gè)混合模式擒抛,可以通過 mixin 來代替 class 定義一個(gè)不含構(gòu)造方法的類:

mixin Musical {
  bool canPlayPiano = false;
  bool canCompose = false;
  bool canConduct = false;

  void entertainMe() {
    if (canPlayPiano) {
      print('Playing piano');
    } else if (canConduct) {
      print('Waving hands');
    } else {
      print('Humming to self');
    }
  }
}

當(dāng)然推汽,我們也可以指定某個(gè)類來使用定義的混合模式,通過 on 關(guān)鍵字:

mixin MusicalPerformer on Musician {
  // ···
}

靜態(tài)變量和函數(shù)

定義靜態(tài)變量和函數(shù)的方法與 Java 類似:

class Point {
  num x, y;
  Point(this.x, this.y);
  static const originalPoint = Point(0, 0);

  static num distanceBetween(Point a, Point b) {
    var dx = a.x - b.x;
    var dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
  }
}

// usage
void main() {
  var a = Point(2, 2);
  var b = Point(4, 4);
  var distance = Point.distanceBetween(a, b);
  assert(2.8 < distance && distance < 2.9);
  print(distance);
}

異步操作

Dart 是單線程執(zhí)行的歧沪,如果進(jìn)行 I/O 操作或進(jìn)行耗時(shí)的操作時(shí)歹撒,程序可能會(huì)發(fā)生阻塞。Dart 庫中的很多函數(shù)都返回 Future 或者 Stream 對(duì)象槽畔,這些方法都是異步執(zhí)行的栈妆,它們可以在建立一個(gè)耗時(shí)操作之后返回,而無需等待耗時(shí)操作執(zhí)行完成厢钧。

我們可以通過兩種方式來實(shí)現(xiàn)異步操作:

  • 通過 asyncawait 實(shí)現(xiàn)
  • 借助于 Future API 來實(shí)現(xiàn)

async 和 await

通過 asyncawait 關(guān)鍵字鳞尔,我們可以輕松實(shí)現(xiàn)異步操作。要使用 await早直,必須要將函數(shù)用 async 修飾寥假,同時(shí)函數(shù)會(huì)返回一個(gè) Future 對(duì)象。簡單用法如下:

Future checkVersion() async {
  try {
    version = await lookUpVersion();
  } catch (e) {
    // React to inability to look up the version
  }
}

生成器

  • 同步生成器 — sync*

    值得注意的是霞扬,同步生成器會(huì)返回 Iterable 對(duì)象:

    Iterable<int> naturalsTo(int n) sync* {
      int k = 0;
      while (k < n) yield k++;
    }
    
  • 異步生成器 — async*

    異步生成器返回 Stream 對(duì)象:

    Stream<int> asynchronousNaturalsTo(int n) async* {
      int k = 0;
      while (k < n) yield k++;
    }
    
  • yield*

    通過 yield* 在遞歸中提升性能:

    Iterable<int> naturalsDownFrom(int n) sync* {
      if (n > 0) {
        yield n;
        yield* naturalsDownFrom(n - 1);
      }
    }
    

將類對(duì)象作為函數(shù)調(diào)用

Dart 允許我們將一個(gè)類的對(duì)象作為函數(shù)來調(diào)用糕韧,只需要實(shí)現(xiàn) call() 函數(shù)即可:

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

未完待續(xù)

此文只是 Dart 征程的一個(gè)起點(diǎn),亦是 Flutter 中的一塊基石喻圃,后續(xù)還有更多進(jìn)階用法和細(xì)節(jié) API 等著我們?nèi)ネ诰蛴┎剩琸eep learning!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末斧拍,一起剝皮案震驚了整個(gè)濱河市雀扶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌肆汹,老刑警劉巖愚墓,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異昂勉,居然都是意外死亡浪册,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門岗照,熙熙樓的掌柜王于貴愁眉苦臉地迎上來村象,“玉大人笆环,你說我怎么就攤上這事『裾撸” “怎么了咧织?”我有些...
    開封第一講書人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長籍救。 經(jīng)常有香客問我习绢,道長,這世上最難降的妖魔是什么蝙昙? 我笑而不...
    開封第一講書人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任闪萄,我火速辦了婚禮,結(jié)果婚禮上奇颠,老公的妹妹穿的比我還像新娘败去。我一直安慰自己,他們只是感情好烈拒,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開白布圆裕。 她就那樣靜靜地躺著,像睡著了一般荆几。 火紅的嫁衣襯著肌膚如雪吓妆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評(píng)論 1 291
  • 那天吨铸,我揣著相機(jī)與錄音行拢,去河邊找鬼。 笑死诞吱,一個(gè)胖子當(dāng)著我的面吹牛舟奠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播房维,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼沼瘫,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了咙俩?” 一聲冷哼從身側(cè)響起耿戚,我...
    開封第一講書人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎暴浦,沒想到半個(gè)月后溅话,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晓锻,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡歌焦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了砚哆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片独撇。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出纷铣,到底是詐尸還是另有隱情卵史,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布搜立,位于F島的核電站以躯,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏啄踊。R本人自食惡果不足惜忧设,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望颠通。 院中可真熱鬧址晕,春花似錦、人聲如沸顿锰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽硼控。三九已至刘陶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間牢撼,已是汗流浹背易核。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留浪默,地道東北人牡直。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像纳决,于是被迫代替她去往敵國和親碰逸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔阔加,今天18年5月份再次想寫文章饵史,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 2,739評(píng)論 2 9
  • Dart重要概念:1,在變量中可以放置的所有東西都是對(duì)象胜榔,而每個(gè)對(duì)象都是類的實(shí)例胳喷。無論數(shù)字、函數(shù)夭织、和null都是對(duì)...
    哥哥是歐巴Vitory閱讀 793評(píng)論 0 1
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,093評(píng)論 1 32
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 3,788評(píng)論 1 10
  • 是或者否吭露,你曾為我停留 有或者沒有,為我動(dòng)心過 夠還是不夠尊惰,沖動(dòng)的理由 對(duì)還是錯(cuò)讲竿,相遇的時(shí)刻 低頭是浮游泥兰,抬頭見蒼...
    范有米閱讀 239評(píng)論 0 0