Dart 基礎 - 3
同步發表於筆者部落格
目的:
- 為公司內部分享的筆記。
- 寫給想由淺入深地了解 Dart 這個程式語言的人。
運算子(Operators)
四則運算、邏輯運算、程式運算等比較基礎的運算部份請參看官方文檔。
在此講一些比較特別的運算子
as, is, is!
// Type test operators
num n = 1.1;
print(n is! int);
print(n is double);
复制代码
true
true
复制代码
條件算符(Conditional expressions)
大部分程式語言都會有三元運算子 ?:
,它可以很簡短的代替 if-else
語法。 Dart 中有幾個比較有趣的寫法 ??
、?.
等。
??
與 ?.
都會判斷左方的運算元是否為 null
,再進行動作。
此範例若有些看不懂,可以看完下面一節 類別(上) 後再回頭看一次這裡。
class Account {String username;String password;Account({username, password}): this.username = username,// 下面兩種寫法是等價的// this.password = (password != null) ? password : 'AutomaticallyGenerateSecretPassword';this.password = password ?? 'AutomaticallyGenerateSecretPassword';@overrideString toString() {return "Account($username, $password)";}
}
复制代码
var a = Account(username: 'Bobson');
print(a);var b = Account();
b?.username = "I'm Groot";
print(b);
复制代码
Account(Bobson, AutomaticallyGenerateSecretPassword)
Account(I'm Groot, AutomaticallyGenerateSecretPassword)
复制代码
級聯符號(Cascade notation)
級聯符號可讓你針對一個物件進行一連串的函數操作,可省下寫重複變數的動作。
不用級聯符號的寫法:
var list = List()
list.insert(0, 123)
list.add(456)
list.addAll([789, 111]);
复制代码
用級聯符號的寫法:
var list = List()..insert(0, 123)..add(456)..addAll([789, 111]);
print(list);
复制代码
[123, 456, 789, 111]
复制代码
類別(Class) - 上篇
物件導向程式(OOP),是軟體程式設計中很重要的一環,打算用較長篇幅講解。
物件導向簡單說,從大到小;從整體應用(業務)邏輯到程式組件,都為他們繪製藍圖(也就是類別
),
而電腦在執行程式時,會依照藍圖製造出成品(也就是物件
或實例
),中間的製造過程統稱實例化
。
直接來看些 Dart 中 OOP 的應用吧。
// Point Class from dart:math
var p1 = Point(1, 2);
var p2 = Point(3, 4);
print("p1: $p1, p2: $p2");
print(p1.distanceTo(p2));
print(p2.magnitude);
复制代码
p1: Point(1, 2), p2: Point(3, 4)
2.8284271247461903
5.0
复制代码
Dart 中的 OOP 與其他 OOP 語言特性並無太多不同,
我找了 Dart 的數學函式庫 dart:math
中的 Point
(二維平面上的點) 作為開篇。
class Point<T extends num> {final T x;final T y;const Point(T x, T y): this.x = x,this.y = y;String toString() => 'Point($x, $y)';.../*** Get the straight line (Euclidean) distance between the origin (0, 0) and* this point.*/double get magnitude => sqrt(x * x + y * y);/*** Returns the distance between `this` and [other].*/double distanceTo(Point<T> other) {var dx = x - other.x;var dy = y - other.y;return sqrt(dx * dx + dy * dy);}...
}
复制代码
類別通常都會包含幾個東西:
- 屬性(property) 或 成員(member) - 物件會用到的變數
- 建構子(constructor) - 可理解成創建(初始化)物件時會調用的函數
- 方法(methods) - 物件會用到的函數
以 Point
對應來說:
- 屬性或成員 -
final T x
(此點的 x 座標)final T y
(此點的 y 座標)
- 建構子 -
const Point(T x, T y)...
- 方法 -
String toString()...
(print 時所顯示的字串),double get magnitude...
(此點與原點的距離),double distanceTo(Point<T> other)...
(此點與另一點的距離)
對應完之後是不是覺得很好理解了呢,這也是 OOP 的迷人之處。
接下來,我們試看看用 Dart 實現數學中複數(complex)的類別吧。
Complex Number (複數) - x + yi (i = √-1) 其中 x 及 y 皆為實數,分別稱為複數之「實部」和「虛部」。
class BaseComplex {num real;num imaginary;@overridebool operator ==(dynamic other) {if (other is! BaseComplex) {return false;} else {return real == other.real && imaginary == other.imaginary;}}@overrideString toString() => "BaseComplex($real, $imaginary)";
}
复制代码
- 屬性或成員 -
num real
(實部)num imaginary
(虛部)
- 建構子 - 無
- 方法 -
bool operator ==(dynamic other)...
(複數物件相等函數)String toString()...
(print 時所顯示的字串),
稍稍分解一下,有兩項額外重點:
- 建構子不寫的話會有一個預設的建構子可以調用,別忘了 Dart 中一次都繼承於
Object
,所以實際上預設是調用了Object
的建構子。 @override
這裝飾子是用來覆寫父類別的方法,Object
中包含了==()
和toString()
。
接著實際建造 BaseComplex
看看吧~
var c1 = BaseComplex();
c1.real = 5;
c1.imaginary = 2;
print(c1.runtimeType);var c2 = BaseComplex()..real = 5..imaginary = 2;
print("c1: $c1, c2: $c2");print(c1 == c2);
复制代码
BaseComplex
c1: BaseComplex(5, 2), c2: BaseComplex(5, 2)
true
复制代码
runtimeType
可顯示程式執行時,此變數的型別是什麼print("c1: $c1, c2: $c2");
print 時會調用到物件的toString
函數,若無覆寫toString
會顯示Instance of 'BaseComplex'
。c1 == c2
中實際上會調用我們覆寫的==
函數。
稍微有些基礎建立類別方法了吧~
要多加一些特性在實際 Complex
物件囉。
class Complex {// Private property(member)num _real;num _imaginary;// Getters & Settersget real => _real;set real(num newReal) => _real = newReal;get imaginary => _imaginary;set imaginary(num newImaginary) => _imaginary = newImaginary;// Traditional way// Complex(num real, num imaginary) { // this.real = real; // this.imaginary = imaginary; // }// Syntactic sugarComplex(this._real, this._imaginary);// Named ConstructorComplex.real(num real) : this(real, 0);Complex.imaginary(num imaginary) : this(0, imaginary);@overridebool operator ==(dynamic other) {if (other is! Complex) {return false;} else {return real == other.real && imaginary == other.imaginary;}}@overrideString toString() {if (imaginary >= 0) {return "$real + ${imaginary}i";} else {return "$real - ${imaginary.abs()}i";}}
}
复制代码
這裡整理一下,加了哪些東西?
- Private property(member) - (相當於 Java 裡的
private
)- Dart 中的類別屬性(成員)前面加
_
,可達到屬性被保護的作用。 - 建造出來的物件 private 屬性無法直接透過
.
獲取。
- Dart 中的類別屬性(成員)前面加
- Getters & Setters - (相當於
JavaBeans
)- 屬於類別中的方法(methods),想要類別中的屬性有讀與寫的權限,可以讓屬性變 private,並寫個自定義的 Get 函數(讀)、Set 函數(寫)。
- 但在物件操作上如此(都用自定義Get 函數和 Set 函數)會變得不方便,所以可直接使用
get
和set
,在 Dart 中針對他們有對應的 keyword 可用。
- 建構子
- 傳統一般的建構子會用大括號來定義其初始的內容。
- 在 Dart 中有更精簡的寫法(Syntactic sugar 語法糖)。
- 命名建構子(Named Constructor)
- 有時類別內會有特別常用的特定型態,可以額外寫成命名建構子。
- 在 Flutter 中可以常常看到這種應用,如
ListView
中就有好幾個命名建構子ListView.builder
、ListView.seperated
、ListView.custom
。
- 初始化列表(Initializer list)
- 在建構子建構物件之前,可以用
:
來設定一些初始值。 - 在 Flutter 源碼中可以常常看到這種應用。
- 在建構子建構物件之前,可以用
你也可以瞧瞧...
參考
- Dart 官方文檔 - Operators
- Dart 官方文檔 - Classes
- Introduction to Dart for Beginners - Intro to Classes and Objects - Part Three
系列文
- Dart 基礎 - 4
Dart 基礎 - 3相关推荐
- Dart 基礎 - 4
同步發表於筆者部落格 目的: 為公司內部分享的筆記. 寫給想由淺入深地了解 Dart 這個程式語言的人. 類別(Class) - 中篇 延續上一節的 類別(Class) - 上篇 方法(Methods ...
- mysql數據庫的增刪改查_MySQL數據庫之基礎增刪改查操作
作者: 守望幸福 最后修改日期:2014-7-27 所操作的MySQL數據庫名:firstdb 所用的兩個表結構如下: student表 number name socre born_d ...
- Windows Phone 7.1 Sensor プログラミング基礎
Windows Phone 7.1 Sensor プログラミング基礎 MSC D1-401セッションのフォローアップ第一弾です. この投稿では.Windows Phone 7.1 Mangoに搭載され ...
- stm32h7内存分配_【STM32H7教程】第25章 STM32H7的TCM,SRAM等五塊內存基礎知識
第25章 STM32H7的TCM,SRAM等五塊內存基礎知識 本章教程為大家介紹STM32H7帶的ITCM,DTCM,AXI SRAM,SRAM1,SRAM2,SRAM3,SRAM4和備份 ...
- JS基礎:Hoisting 變量提升、TDZ 暫時性死區(Temporal Dead Zone)
JS 基礎:Hoisting 變量提升.TDZ 暫時性死區(Temporal Dead Zone) 文章目錄 JS 基礎:Hoisting 變量提升.TDZ 暫時性死區(Temporal Dead Z ...
- 從turtle海龜動畫 學習 Python - 高中彈性課程系列 3 烏龜繪圖 所需之Python基礎
"Talk is cheap. Show me the code." ― Linus Torvalds 老子第41章 上德若谷 大白若辱 大方無隅 大器晚成 大音希聲 大象無形 道 ...
- pytorch操作基礎(二)——基礎
深度學習(二)--基礎 搭建好了pytorch後先不急着操作,先了解神經網絡是一件很重要的事情. pytorch基礎 -Tensor 即張量,表示多維的矩陣,pytorch裏面處理的單位就是一個個張量 ...
- 【繁中】Python 教學 爬蟲基礎
Python 文章目录 Python __init__.__new__和__call__ 型態 len(資料) Tuple 特殊字串 成員運算子 input 集合Set 基本語法 Set 運算子 字典 ...
- JS基礎:Closure 閉包
JS 基礎:Closure 閉包 文章目錄 JS 基礎:Closure 閉包 簡介 參考 正文 IIFE 立即執行函數(Immediately Invoked Functions Expression ...
最新文章
- python变量运算符_Python基础 — 变量和运算符
- 合成存储方法,局部/全局变量
- Android开发学习笔记-自定义组合控件
- LNMP与CA认证的童话故事
- 95-190-300-源码-window-Window Assigner
- 特斯拉蛇形充电机器人_特斯拉将内存设备锁入手套箱内 确保哨兵模式/TeslaCam数据安全...
- Autograd看这一篇就够了!
- 【Oracle】ORA-30042: Cannot offline the undo tablespace
- UVA10738 Riemann vs Mertens【欧拉筛法】
- 【转】程序员的十种级别
- RHEL 5基础篇—管理系统计划任务
- [16]manjaro安装nvidia驱动
- 免安装版VSCode配置(便携模式)
- 表示微型计算机系统稳定性,计算机选择题
- 使用VIA(VCC)制作coco数据集
- 圆瓶、扁瓶、三色瓶砖、数百品牌分选,弓叶科技的分选神技
- linux centos服务器安全初级防御
- 浅谈模块化UPS对提高数据中心适应性的作用
- Documents最新版 2021版本 下载试用
- 基于ssm高校共享单车管理系统 (源代码+数据库) 604
热门文章
- java绝对路径和相对路径_Java文件路径,绝对路径和规范路径
- scala中命名参数函数_Scala中的命名参数和默认参数值
- scala案例_Scala案例类和案例对象深入(第2部分)
- 十分钟快速上手结巴分词
- 30. Substring with Concatenation of All Words
- shell学习笔记二
- mysql “Access denied for user 'root'@'localhost'
- 【大数相乘】LeetCode 43. Multiply Strings
- 【归并排序+递归】LeetCode 148. Sort List
- 【难题+重点】剑指offer——面试题40:数组中只出现一次的数字