Dart是由google開發的語言
目的是讓同一套程式碼可以跨平台編譯
注意,跟JAVA編譯一次後到處執行是不同的喔,Dart雖然也只需要寫一次程式碼,但是如果要跨平台需要分別編譯出不同平台的執行檔
Dart跨平台的方式是使用Flutter這個框架,讓同一套Dart程式碼可以分別編譯出在iOS跟在Andorid平台上執行的執行檔
原本半官方的Flutter Desktop Embedding整合進Flutter後甚至能夠交叉編譯成Windows,MacOS,linux的執行檔
如果你需要開發Web,Dart也能編譯成Javascript,讓你於瀏覽器上執行
Dart的推出讓google有了一套完整的生態,後端由golang吃下,而前端則使用可以跨平台的Dart
(甚至你希望的話,Dart也能拿來開發後端)
但是Dart也不是完全沒有缺點
比方說在Android或iOS上,如果你必須處理底層的事物,那還是必須要倚賴Java及Swift
(這點Dart就比不上kotlin了,畢竟kotlin可以直接拿Java的函式庫來用)
尤其在iOS由於為了安全性有很多系統層級的事情是沒有開放給外部使用,只能使用Swift的api做轉接,此時若是你不是使用Swift就頭大了
(比方說iOS的簡訊處理,設定上是隱藏的)
另外還有個可怕的大魔王,同樣由七巨頭的Facebook推出的React Native
使用工程師們已經很熟悉的Javascript,同時原本就是用來編寫網頁前端的框架延伸而出
變成可以開發用於iOS及Android上的程式
更何況還有比Dart更為豐富的套件庫(雖然Dart有急起直追的趨勢,不過現在還是RN比較多)
因此有人說Flutter唯一的缺點就是使用了Dart,沒辦法接納已經很完整的js生態
目前Flutter能夠跟RN一拼的大概就是效能,但是這個效能是有代價的
兩個網頁並不是同一個網頁,單純想展示兩者在畫面的Render上的不同
react還可以分辨出每個元件的在做什麼,但是flutter完全不行(或者該說現在的人類還跟不上嗎?)
於是乎,Dart變成一種看上去很美但是實際上(目前)並沒有到他理想中的實用性
或許如果不需要寫太底層,比方說用於公司內部的系統控管之類的應用上,就可以使用Dart讓你跨平台
做一套可以在PC也能在手機上的程式
說了這麼多,我們來動手寫dart吧
我們今天先不教Flutter,這樣使用docker的同學才能跟上進度
在你的工作目錄下面建立一個附檔名為.dart的檔案
然後貼上下面的程式碼吧
import 'dart:io';
import 'dart:math' as math;
void main() {
print("Tell me what you want to do:");
print("(1)T to H (2)H to T");
var input = stdin.readLineSync();
switch(input){
case "1":
print("Please enter the number:");
var number = stdin.readLineSync();
print(t2h(number));
break;
case "2":
print("Please enter the number:");
var number = stdin.readLineSync();
print(h2t(number));
break;
default :
print("Wrong selection");
}
}
String t2h(String number) {
var num = int.parse(number);
for (var i = 0; i < 16; i++){
for (var j = 0;j < 16; j++){
for (var k = 0; k < 16; k++){
if (math.pow(16,2)*i+math.pow(16,1)*j+math.pow(16,0)*k == num)
return returnAE(i)+returnAE(j)+returnAE(k);
}
}
}
}
String returnAE(int number){
switch (number){
case 10: return "A";
case 11: return "B";
case 12: return "C";
case 13: return "D";
case 14: return "E";
case 15: return "F";
default : return number.toString();
}
}
int h2t(String number){
int output = 0;
int i = 0;
while (i<number.length){
output += AEreturn(number.substring(i,i+1))*(math.pow(16,number.length-i-1));
i++;
}
return output;
}
int AEreturn(String input){
switch (input){
case "A": return 10;
case "B": return 11;
case "C": return 12;
case "D": return 13;
case "E": return 14;
case "F": return 15;
default: return int.parse(input);
}
}
之後docker的使用者進行掛載後切換到掛載的目錄下執行
docker container run -it -v ${PWD}:/home/Dart google/dart /bin/bash
或是直接執行
docker container run -it -v ${PWD}:/home/Dart google/dart dart /home/Dart/convert.dart
本地有安裝的人可以直接用
dart convert.dart
這樣就可以開始玩你的程式拉
官方有推薦的程式碼風格
官方推薦的tab也不是往常的4個空格,而是跟RN相同的2個空格
但是為了確保我們的程式名稱跟以前寫過的一樣,並沒有完全按照官方的寫法
也能使用官方的工具
dartfmt
來讓你的程式碼風格接近於官方風格(有沒有golang的感覺?)
也能把程式碼貼到這裡後按下上方的Format
程式開頭的import
import 'dart:io';
import 'dart:math' as math;
是為了要引入冪次計算跟輸入輸出
dart也是編譯式的語言,因此會需要main方法
void main() {}
注意dart的行尾是需要;的喔
print("Tell me what you want to do:");
print("(1)T to H (2)H to T");
var input = stdin.readLineSync();
輸出使用print
輸入則使用stdin.readLineSync()
print是Dart提供的基本輸出
由於我們已經引入了dart:io這個用來做input跟output的library,我們也能這麼做
stdout.writeln("Tell me what you want to do:");
stdout.writeln("(1)T to H (2)H to T");
var input = stdin.readLineSync();
Dart的switch結構跟常見的差不多
switch(input){
case "1":
print("Please enter the number:");
var number = stdin.readLineSync();
print(t2h(number));
break;
case "2":
print("Please enter the number:");
var number = stdin.readLineSync();
print(h2t(number));
break;
default :
print("Wrong selection");
}
注意每個case需要使用break隔開
Dart是靜態型別的語言,我們必須提前定義好他們輸入及輸出的型別
輸出型別 方法名稱(輸入型別 輸入變數){
}
因此會長這樣
String t2h(String number) {
var num = int.parse(number);
for (var i = 0; i < 16; i++){
for (var j = 0;j < 16; j++){
for (var k = 0; k < 16; k++){
if (math.pow(16,2)*i+math.pow(16,1)*j+math.pow(16,0)*k == num)
return returnAE(i)+returnAE(j)+returnAE(k);
}
}
}
}
輸入值及輸出值的型別都是string
並且沒有宣告方法的關鍵字
只要格式對了Dart就會自動判定你寫的是方法
跟C#及部份語言類似
var這個宣告詞會自動幫你判定型別
另外由於Dart是強型別的語言,因此這邊需要轉型
字串轉型成數值的方式是
var int = int.parse(string)
反過來則是
int.toString();
Dart的迴圈也是常見的
for (var i=0; i < 16; i++){
}
的結構
注意迴圈宣告的起始值一樣要宣告,因此你會看到var這個關鍵字
if的結構也是常見的
if (math.pow(16,2)*i+math.pow(16,1)*j+math.pow(16,0)*k == num)
return returnAE(i)+returnAE(j)+returnAE(k);
這邊由於我們確認完if的條件後需要執行的程式只有一行
因此可以省略{}
如果不習慣這個結構可以加回去,同樣可以執行成功
這段if裡面我們用到了冪次的計算
結構長這樣
math.pow(x,exp)
x可以是int,exp如果也是非負數的int的話,那麼輸出值就會是int的型別
反之則回傳double型別
詳細的用法可以看這裡
我們往下看returnAE裡面的程式吧
String returnAE(int number){
switch (number){
case 10: return "A";
case 11: return "B";
case 12: return "C";
case 13: return "D";
case 14: return "E";
case 15: return "F";
default : return number.toString();
}
}
這邊沒有break是因為我們使用了return
break本來的目的就是要中止case的判斷
而return則直接中止方法,並回傳值,因此不需要使用break告知程式碼我們要結束switch了
我們來看跟t2h相對的h2t這個方法吧
int h2t(String number){
int output = 0;
int i = 0;
while (i<number.length){
output += AEreturn(number.substring(i,i+1))*(math.pow(16,number.length-i-1));
i++;
}
return output;
}
while的用法跟常見的方法相同,這裡不多做描述
string.length
則是取出字串長度屬性的方式,型別為int
因此在math.pow內不需要轉型即可當作輸入
math.pow(16,number.length-i-1)
迴圈的內部雖然我們使用字串內建的substring方法來將字串內部的字元取出
但我們也能這樣寫
output += AEreturn(number[i])*(math.pow(16,number.length-i-1));
把字串當作字元的陣列來取出字元
以上就是Dart的基本語法拉
來複習今天學的語法吧
雖然Dart是前端語言,但實際上要作為後端也是可行的
如同我們今天寫的終端機執行程式
但真正要發揮Dart的語言特性還是必須要配合Flutter
雖然相較於火熱的React Native,起步晚了兩年的Flutter不管在使用人數上還是library的數量上都少了許多
但是從Java或是C++轉過來的人在學習上並不會困難,因此也能當作後端工程師的前端備選語言
而且在flutter的youtube頻道上還算活躍
又有google這個靠山在
算是值得期待的語言
明天,我們來做這十五種語言的總結吧
如果有任何寫不清楚或是觀念沒有很明白的話請留言告知我
會盡快補上
如果有任何寫錯的地方也麻煩留言告知我
會盡快修正
感謝各位
以我用了 ReactNative 半年以及 Flutter 2 年的經驗, 我只能說, ReactNative 呼叫底層模組 Debug 的效能真是讓人欲哭無淚 (也許現在有改變, 但是 FB 的開發文件真的是....). 所以 Flutter 出來我就跳船了.
Flutter 生態系跟 React 比起來當然還是差很多, 但是需要大量與底層整合的工作, Flutter 給我的體驗比 React Native 好太多了. 也許 UI Debug 比較不順手, 但是我的經驗是 Flutter 在 UI 能做的不會輸給 JS.
至於 Dart, 我覺得是一個實用性很高的語言, 有夠用的物件導向與泛型實作. 也有現代語言的簡潔. 雖然不是100分但是也有87分.
好有說服力@@我信你了