dart基礎(chǔ)和kotlin不同之處

變量

聲明變量

聲明可以有兩種方式,一種是不指定類型,即使用var關(guān)鍵字
這種發(fā)方式和kotlin一樣

var name = 'Bob';

另一種是明確指定類型(Optional types),這種和java一樣

String name = 'Bob';

因?yàn)橛蓄愋屯茖?dǎo),所以兩種實(shí)現(xiàn)效果一樣,官方推薦在函數(shù)內(nèi)的本地變量盡量使用var聲明。

在變量類型并不明確的情況下,可以使用dynamic關(guān)鍵字,這種dynamic和kotlin里的any一樣

dynamic name = 'Bob';

訪問限定符

Dart 沒有類似于 Java 那樣的 public、protected 和 private 成員訪問限定符。如果一個(gè)標(biāo)識(shí)符以下劃線 (_) 開頭則表示該標(biāo)識(shí)符在庫內(nèi)是私有的

Final 和 Const

使用過程中從來不會(huì)被修改的變量, 可以使用 final 或 const,而不是 var 或者其他類型,F(xiàn)inal 變量的值只能被設(shè)置一次; Const 變量在編譯時(shí)就已經(jīng)固定 (Const 變量 是隱式 Final 的類型) 。最高級(jí) final 變量或類變量在第一次使用時(shí)被初始化。

內(nèi)建類型

Dart 語言支持以下內(nèi)建類型:

Number
String
Boolean
List (也被稱為 Array)
Map
Set
Rune (用于在字符串中表示 Unicode 字符)
Symbol

后兩個(gè)kotlin沒有,前面幾個(gè)和kotlin一樣

String

Dart 字符串是一組 UTF-16 單元序列。 字符串通過單引號(hào)或者雙引號(hào)創(chuàng)建。
字符串可以通過 ${expression} 的方式內(nèi)嵌表達(dá)式。和kotlin一樣。

使用連續(xù)三個(gè)單引號(hào)或者三個(gè)雙引號(hào)實(shí)現(xiàn)多行字符串對象的創(chuàng)建,(和kotlin不一樣)

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

使用 r 前綴,可以創(chuàng)建 “原始 raw” 字符串:(kotlin沒有)

var s = r"In a raw string, even \n isn't special.";

List,和kotlin一樣

  var list = [1, 2, 3];

Set

var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
var names = {}; // 這樣會(huì)創(chuàng)建一個(gè) Map ,而不是 Set 。

Map

和json字符串一樣,

var gifts = {
  // Key:    Value
  'first': 'partridge',
  'second': 'turtledoves',
  'fifth': 'golden rings'
};

Rune

在 Dart 中, Rune 用來表示字符串中的 UTF-32 編碼字符。
示 Unicode 編碼的常用方法是, \uXXXX, 這里 XXXX 是一個(gè)4位的16進(jìn)制數(shù)。 例如,心形符號(hào) (?) 是 \u2665。 對于特殊的非 4 個(gè)數(shù)值的情況, 把編碼值放到大括號(hào)中即可。 例如,emoji 的笑臉 (?) 是 \u{1f600}。

下面是示例演示了 Rune 、 16-bit code units、 和 32-bit code points 之間的關(guān)系。

main() {
  var clapping = '\u{1f44f}';
  print(clapping);
  print(clapping.codeUnits);
  print(clapping.runes.toList());

  Runes input = new Runes(
      '\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d}');
  print(new String.fromCharCodes(input));
}

Symbol

一個(gè) Symbol 對象表示 Dart 程序中聲明的運(yùn)算符或者標(biāo)識(shí)符
通過字面量 Symbol ,也就是標(biāo)識(shí)符前面添加一個(gè) # 號(hào),來獲取標(biāo)識(shí)符的 Symbol 。

#radix
#bar

函數(shù)

可選參數(shù)

可選參數(shù)可以是命名參數(shù)或者位置參數(shù),但一個(gè)參數(shù)只能選擇其中一種方式修飾。
命名可選參數(shù)

調(diào)用函數(shù)時(shí),可以使用指定命名參數(shù) paramName: value。 例如:

enableFlags(bold: true, hidden: false);

定義函數(shù)是,使用 {param1, param2, …} 來指定命名參數(shù):

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

使用 @required 注釋表示參數(shù)是 required 性質(zhì)的命名參數(shù),required參數(shù)調(diào)用時(shí)必須要傳, 該方式可以在任何 Dart 代碼中使用(不僅僅是Flutter)。

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

位置可選參數(shù)

將參數(shù)放到 [] 中來標(biāo)記參數(shù)是可選的:

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

默認(rèn)參數(shù)值

在定義方法的時(shí)候,可以使用 = 來定義可選參數(shù)的默認(rèn)值。 默認(rèn)值只能是編譯時(shí)常量。 如果沒有提供默認(rèn)值,則默認(rèn)值為 null。

下面是設(shè)置可選參數(shù)默認(rèn)值示例:

/// 設(shè)置 [bold] 和 [hidden] 標(biāo)志 ...
void enableFlags({bool bold = false, bool hidden = false}) {...}

// bold 值為 true; hidden 值為 false.
enableFlags(bold: true);

函數(shù)是一等對象

一個(gè)函數(shù)可以作為另一個(gè)函數(shù)的參數(shù)。 例如:

void printElement(int element) {
  print(element);
}

var list = [1, 2, 3];

// 將 printElement 函數(shù)作為參數(shù)傳遞。
list.forEach(printElement);

詞法閉包

閉包 即一個(gè)函數(shù)對象,即使函數(shù)對象的調(diào)用在它原始作用域之外, 依然能夠訪問在它詞法作用域內(nèi)的變量。
函數(shù)可以封閉定義到它作用域內(nèi)的變量。 接下來的示例中, makeAdder() 捕獲了變量 addBy。 無論在什么時(shí)候執(zhí)行返回函數(shù),函數(shù)都會(huì)使用捕獲的 addBy 變量。

/// 返回一個(gè)函數(shù),返回的函數(shù)參數(shù)與 [addBy] 相加。
Function makeAdder(num addBy) {
 return (num i) => addBy + i;
}

void main() {
 // 創(chuàng)建一個(gè)加 2 的函數(shù)。
 var add2 = makeAdder(2);

 // 創(chuàng)建一個(gè)加 4 的函數(shù)。
 var add4 = makeAdder(4);

 assert(add2(3) == 5);
 assert(add4(3) == 7);
}

級(jí)聯(lián)運(yùn)算符 (..)(kotlin沒有)

級(jí)聯(lián)運(yùn)算符 (..) 可以實(shí)現(xiàn)對同一個(gè)對像進(jìn)行一系列的操作。 除了調(diào)用函數(shù), 還可以訪問同一對象上的字段屬性。 這通??梢怨?jié)省創(chuàng)建臨時(shí)變量的步驟, 同時(shí)編寫出更流暢的代碼。

考慮一下代碼:

querySelector('#confirm') // 獲取對象。
  ..text = 'Confirm' // 調(diào)用成員變量。
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'));

第一句調(diào)用函數(shù) querySelector() , 返回獲取到的對象。 獲取的對象依次執(zhí)行級(jí)聯(lián)運(yùn)算符后面的代碼, 代碼執(zhí)行后的返回值會(huì)被忽略。

上面的代碼等價(jià)于:

var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));

級(jí)聯(lián)運(yùn)算符可以嵌套,例如:

final addressBook = (AddressBookBuilder()
      ..name = 'jenny'
      ..email = 'jenny@example.com'
      ..phone = (PhoneNumberBuilder()
            ..number = '415-555-0100'
            ..label = 'home')
          .build())
    .build();

賦值運(yùn)算符??=

使用 = 為變量賦值。 使用 ??= 運(yùn)算符時(shí),只有當(dāng)被賦值的變量為 null 時(shí)才會(huì)賦值給它。

// 將值賦值給變量a
a = value;
// 如果b為空時(shí),將變量賦值給b,否則,b的值保持不變。
b ??= value;

類型判定運(yùn)算符

as, is, 和 is! 運(yùn)算符用于在運(yùn)行時(shí)處理類型檢查

異常

catch

捕獲異??梢员苊猱惓@^續(xù)傳遞(除非重新拋出( rethrow )異常)。 可以通過捕獲異常的機(jī)會(huì)來處理該異常:

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // 一個(gè)特殊的異常
  buyMoreLlamas();
} on Exception catch (e) {
  // 其他任何異常
  print('Unknown exception: $e');
} catch (e) {
  // 沒有指定的類型,處理所有異常
  print('Something really unknown: $e');
}

捕獲語句中可以同時(shí)使用 on 和 catch ,也可以單獨(dú)分開使用。 使用 on 來指定異常類型, 使用 catch 來 捕獲異常對象。

catch() 函數(shù)可以指定1到2個(gè)參數(shù), 第一個(gè)參數(shù)為拋出的異常對象, 第二個(gè)為堆棧信息

try {
  // ···
} on Exception catch (e) {
  print('Exception details:\n $e');
} catch (e, s) {
  print('Exception details:\n $e');
  print('Stack trace:\n $s');
}

finally

不管是否拋出異常, finally 中的代碼都會(huì)被執(zhí)行。 如果 catch 沒有匹配到異常, 異常會(huì)在 finally 執(zhí)行完成后,再次被拋出:

對象

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

class Point {
  num x, y;

  // 在構(gòu)造函數(shù)體執(zhí)行前,
  // 語法糖已經(jīng)設(shè)置了變量 x 和 y。
  Point(this.x, this.y);
}

命名構(gòu)造函數(shù)

使用命名構(gòu)造函數(shù)可為一個(gè)類實(shí)現(xiàn)多個(gè)構(gòu)造函數(shù), 也可以使用命名構(gòu)造函數(shù)來更清晰的表明函數(shù)意圖

class Point {
  num x, y;

  Point(this.x, this.y);

  // 命名構(gòu)造函數(shù)
  Point.origin() {
    x = 0;
    y = 0;
  }
}

初始化列表

除了調(diào)用超類構(gòu)造函數(shù)之外, 還可以在構(gòu)造函數(shù)體執(zhí)行之前初始化實(shí)例變量。 各參數(shù)的初始化用逗號(hào)分隔。

// 在構(gòu)造函數(shù)體執(zhí)行之前,
// 通過初始列表設(shè)置實(shí)例變量。
Point.fromJson(Map<String, num> json)
    : x = json['x'],
      y = json['y'] {
  print('In Point.fromJson(): ($x, $y)');
}

重定向構(gòu)造函數(shù)

有時(shí)構(gòu)造函數(shù)的唯一目的是重定向到同一個(gè)類中的另一個(gè)構(gòu)造函數(shù)。 重定向構(gòu)造函數(shù)的函數(shù)體為空, 構(gòu)造函數(shù)的調(diào)用在冒號(hào) (:) 之后.
和kotlin的擴(kuò)展方法寫法類型

class Point {
  num x, y;

  // 類的主構(gòu)造函數(shù)。
  Point(this.x, this.y);

  // 指向主構(gòu)造函數(shù)
  Point.alongXAxis(num x) : this(x, 0);
}

常量構(gòu)造函數(shù)

如果該類生成的對象是固定不變的, 那么就可以把這些對象定義為編譯時(shí)常量。 為此,需要定義一個(gè) const 構(gòu)造函數(shù), 并且聲明所有實(shí)例變量為 final。

class ImmutablePoint {
  static final ImmutablePoint origin =
      const ImmutablePoint(0, 0);

  final num x, y;

  const ImmutablePoint(this.x, this.y);
}

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

當(dāng)執(zhí)行構(gòu)造函數(shù)并不總是創(chuàng)建這個(gè)類的一個(gè)新實(shí)例時(shí),則使用 factory 關(guān)鍵字。 例如,一個(gè)工廠構(gòu)造函數(shù)可能會(huì)返回一個(gè) cache 中的實(shí)例, 或者可能返回一個(gè)子類的實(shí)例。

以下示例演示了從緩存中返回對象的工廠構(gòu)造函數(shù)

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

  // 從命名的 _ 可以知,
  // _cache 是私有屬性。
  static final Map<String, Logger> _cache =
      <String, Logger>{};

  factory Logger(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
    } else {
      final logger = Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }

  Logger._internal(this.name);

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

為類添加功能: Mixin

Mixin 是復(fù)用類代碼的一種途徑, 復(fù)用的類可以在不同層級(jí),之間可以不存在繼承關(guān)系。

通過 with 后面跟一個(gè)或多個(gè)混入的名稱,來 使用 Mixin , 下面的示例演示了兩個(gè)使用 Mixin 的類

class Musician extends Performer with Musical {
// ···
}

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

過創(chuàng)建一個(gè)繼承自 Object 且沒有構(gòu)造函數(shù)的類,來 實(shí)現(xiàn) 一個(gè) Mixin 。 如果 Mixin 不希望作為常規(guī)類被使用,使用關(guān)鍵字 mixin 替換 class

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

  void entertainMe() {}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容