Flutter/Dart第06天:Dart基礎語法詳解(變數)

来源:https://www.cnblogs.com/obullxl/archive/2023/10/01/NTopic2023100101.html
-Advertisement-
Play Games

前面幾天的學習,我們瞭解了Dart語言的特性(基礎語法概覽、迭代集合、非同步編程和Mixin高級特性)。今天我們深入學習Dart的變數,包括:空安全(Null safety)、變數預設值、延遲變數(late)、final變數和const常量…… ...


Dart官網文檔:https://dart.dev/language/variables

重要說明:本博客基於Dart官網文檔,但並不是簡單的對官網進行翻譯,在覆蓋核心功能情況下,我會根據個人研發經驗,加入自己的一些擴展問題和場景驗證。

Dart中的變數

變數是一個對象的引用,引用名就是變數的名稱;就算引用是null的變數也一樣。

變數有3種定義方式:var關鍵字,顯示類型Object/dynamic類型。

var varName = 'Tom';
String strName = 'Tom';
Object objName = 'Tom';
dynamic dynName = 'Tom';

最佳實戰:對於局部變數,優先使用var關鍵字,其次為顯示類型,再次為Object,不推薦使用dynamic(原因:容易引發運行時錯誤,後續的學習會講到)。

當使用var關鍵字定義的變數,Dart會根據值內容,推導出變數的實際類型,如上訴代碼varName變數最終為String類型。

Null safety空安全

Dart語言強制健壯空安全。空安全可以防止意外使用null而導致的錯誤(還記得在Java編程中,在很多對象使用的地方,我們都需要進行null判斷,以防止NPE的發生)。Dart在編譯期間,就會進行null潛在錯誤檢測分析,從而防止這些錯誤的發生(註意:並不是所有場景都能檢測分析到,後面章節會講到)。

代碼樣例:如下代碼,變數strName的預設值為null,在其他編程語言如Java語言中,下麵的代碼是合法的,但是在運行時,當執行strName.length時會引發NPE異常;但是在Dart語言中,以下代碼是非法的(無法編譯),因此阻止發生NPE等這些潛在的錯誤。

String strName;
print(strName.length)

Dart為了強制執行空安全,有3個關鍵改變

  1. 如果明確希望某個變數、參數或者其他組件是可以為null的,那麼需要在類型後面增加一個?標識:
String? name  // `name`的值可能為`null`, 或者為某個字元串
String name   // `name`的值只能是某個字元串,不能為`null`
  1. Dart的變數在使用之前,必須被初始化。可空變數(含有?標識)的預設值為null,即預設初始化為null,因此無需顯示的賦值初始化;而非空變數因沒有預設值,因此必須顯示賦值初始化。
  2. 禁止直接訪問可空類型的屬性或者表達式方法,包括訪問null對象的hashCodetoString()方法(記住:Dart中一起皆對象,null也是),也會引發錯誤。

Dart空安全通過以上3個關鍵改變,保證null潛在錯誤在代碼編寫階段就能被前置發現,而不是等到代碼運行時。

變數預設值

第2章節中,其實已經提到一點:任何變數在使用之前,必須被初始化;可空變數因為預設值為null,因此可無需顯示初始化;非空變數必須顯示初始化。

特別註意:非空變數只需要確保它在被使用時已經初始化即可,而不是必須在申明的時候。如下代碼,變數lineCount在申明時並未初始化,但是在print被使用時,Dart語言檢測到它已經被初始化了,因此如下代碼是空安全有效代碼。

// 申明:未被初始化
int lineCount;

if (weLikeToCount) {
  lineCount = countLines();
} else {
  lineCount = 0;
}

// 使用:Dart檢測到已經被初始化,因此是可以使用
print(lineCount);

late延遲變數

頂級變數和類變數會延遲初始化,當第一次使用到這些變數時,初始化代碼的邏輯才會被執行(即:延遲初始化)。

在大多數情況下,Dart可以檢測並分析一個非空變數在使用時已經初始化,但是在有些場景下,Dart無法檢測分析或者檢測分析會失效。最常見的2種場景:頂級變數實例變數,Dart無法確定它們在被使用時是否已經被初始化了。

如果我們明確一個非空變數在被使用之前能完成初始化(但Dart卻無法檢測到),可通過增加late關鍵字,告訴Dart該變數為延遲變數,在被使用之前確保能被初始化。當然,對於late延遲變數,在被使用時卻並沒有初始化,那麼使用它同樣會導致運行時錯誤

late String description;

void main() {
  description = 'Feijoada!';
  print(description);
}

late延遲變數主要處理以下2種場景:

  1. 這些變數並不是必須的,同時初始化它們非常耗時或者浪費資源(如網路交互等)。
  2. 在初始化實例變數時,需要用到實例本身。

代碼樣例:如下代碼,當變數temperature在第1次被使用時,才會被調用readThermometer()方法,即該方法僅僅被調用1次。

late String temperature = readThermometer();

final變數和const常量

最佳實踐:如果我們明確一個變數在被初始化之後,它的引用值再也不會變化,那麼使用final或者const修飾,而不是使用var者顯示類型

  1. const變數隱式為final變數
  2. const變數是編譯期的常量變數
  3. 實例變數可以是final變數但不能是const變數(原因:實例在運行時才能確定,因此其變數無法作為編譯期常量)
final name = 'Bob';
final String nickname = 'Bobby';
const bar = 1000000;
const double atm = 1.01325 * bar;

特別註意:const不僅可以申明如上代碼的常量變數,它也可以用於申明創建常量值,也可以用於申明創建常量值的構造器(還記得第2天學習內容:const構造函數?);同時,任何變數,都可以有常量值。

// 1. 常量值
var foo = const [];
final bar = const [];
const baz = []; // 等同:`const []`

// 2. 非final/const變數,它的常量值可以更新
foo = const [1, 2, 3];

特別註意:常量的定義,可以包含類型檢測、類型轉換、集合過濾和集合展開操作符。

// `i`是一個`Object`類型常量,它的值是int數字值
const Object i = 3;

// 1. 類型轉換
const list = [i as int];

// 2. 類型檢測和集合過濾
const map = {if (i is int) i: 'int'};

// 3. 類型檢測、集合過濾、集合展開
const set = {if (list is List<int>) ...list};

final變數const常量總結:

  1. final變數不可修改,但是它的值是可以更新
  2. const常量不可修改,同時它的值也不可以更新,即它的值是不可變的(immutable)。
void main() {
  // 1. final變數
  final finalList = [1, 2, 3];
  print('1.1 final變數: $finalList');

  // 輸出:1.1 final變數: [1, 2, 3]

  finalList
    ..add(4)
    ..add(5);
  print('1.2 final變數: $finalList');

  // 輸出:1.2 final變數: [1, 2, 3, 4, 5]

  // 2. const常量
  const constList = ['a', 'b', 'c'];
  print('2.1 const常量: $constList');

  // 輸出:2.1 const常量: [a, b, c]

  constList
    ..add('c')
    ..add('d');
  print('2.2 const常量: $constList');

  // 錯誤:
  // Unhandled exception:
  // Unsupported operation: Cannot add to an unmodifiable list
  // #0      UnmodifiableListMixin.add (dart:_internal/list.dart:114:5)
}

我的本博客原地址:https://ntopic.cn/p/2023100101


本文作者:奔跑的蝸牛,轉載請註明原文鏈接:https://ntopic.cn


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 面積圖,或稱區域圖,是一種隨有序變數的變化,反映數值變化的統計圖表。 面積圖也可用於多個系列數據的比較。這時,面積圖的外觀看上去類似層疊的山脈,在錯落有致的外形下表達數據的總量和趨勢。面積圖不僅可以清晰地反映出數據的趨勢變化,也能夠強調不同類別的數據間的差距對比。 面積圖的特點在於,折線與自變數坐標 ...
  • 用Rust手把手編寫一個wmproxy(代理,內網穿透等), 通訊協議源碼解讀篇 項目 ++wmproxy++ gite: https://gitee.com/tickbh/wmproxy github: https://github.com/tickbh/wmproxy 事件模型的選取 OS線程, ...
  • 這裡想補充下上個文章,感覺有點不太行。因為每次設計新的表結構就要去更新一下,所以,乾脆隨著我要做的功能去展示我的表結構設計,最終再把所有的表結構包括sql語句統計出來,感覺這樣更新會方便很多~ 這個文章主要是發送郵件的功能。之前提過,我不是一下子把後端全部完成,然後再一下子搞定後端。所以我前後端是要 ...
  • 前言 Hyper-V安裝文檔:在 Windows 10 上安裝 Hyper-V CentOS 系統下載:CentOS 國內鏡像源 8.5.2111 作者:易墨 發佈時間:2023.10.01 原文地址:https://www.cnblogs.com/morang/p/devops-hyperv-ce ...
  • 1. 複製切換 1.1. 複製是高可用性的基礎 1.1.1. 總是保留一份持續更新的副本數據,會讓災難恢復更簡單 1.2. “切換副本”(promoting a replica)和“故障切換”(failing over)是同義詞 1.2.1. 意味著源伺服器不再接收寫入,並將副本提升為新的源伺服器 ...
  • [webpack中文文檔](概念 | webpack 中文文檔 | webpack中文文檔 | webpack中文網 (webpackjs.com)): 本質上,webpack 是一個用於現代 JavaScript 應用程式的 靜態模塊打包工具。當 webpack 處理應用程式時,它會在內部從一個或 ...
  • 1 StyleSheet 一張 StyleSheet 由一系列 Rules 組成,這些 Rules 可以分成 2 大類: 1 Style Rule 2 At-Rule 下麵的例子展示了 Style Rule 和 At-Rule: // Style Rule div { background-colo ...
  • 代碼中在使用JUC、消息隊列、回調函數、消息中間件等提高程式性能的方式進行非同步處理時,一定要分清主次,哪些邏輯必須在主線程執行,哪些邏輯可以非同步處理。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...