世界上沒有一種能夠各個領域通吃的語言,爲了應對不一樣的場景和需求,咱們擺脫不了要學習一門新的語言。最近準備入坑 Flutter
(技術儲備),學了點 Dart, 一點心得分享給你們。前端
大綱程序員
我想看這篇文章的應該都是程序員了吧?都有本身熟悉的語言,這就好辦了,咱們能夠複用已有的認知去快速學習一門新語言。若是你是小白,這篇文章可能不適合你編程
肯定語言的定位和場景。別再說 PHP 是最好的語言了,你們都知道。每一門語言都有本身定位和適用場景,爲了解決不一樣的問題。因此學習一門語言的時候,首先要了解語言的定位和領域,這樣你才能明白爲何語言設計者設計某個特性的動機。例如:設計模式
JavaScript
:瀏覽器腳本語言霸主, 寫前端確定繞不開 JavaScript 啦。一門十幾天搞出來的語言,就不要問 [] == ![] // true
是什麼動機了, 不要學這些糟粕。Dart
: 針對客戶端('Flutter')優化語言, 當初號稱要取代 JavaScript, 官方本身的定位就是客戶端Go
: 聽說是 C++
編譯速度慢倒逼出來的語言。因此你能夠站在 C++ 的對立面去思考它的設計:例如 簡單的語法、高速編譯、垃圾回收、高性能、高併發。半數是爲了解決 C++ 的問題。適用於服務器編程、分佈式、網絡編程、雲平臺。Rust
: 系統編程語言,C/C++
最有力的挑戰者固然,也有一些語言只有在特定平臺或場景才能使用,這種沒辦法,這屬於商業壁壘。例如數組
Swift/Objective-C
基本只能用於 Apple 平臺,儘管 Swift 開源,也能夠跑在 Linux 上,但除了 Apple 應用開發,不多看到 Swift 的身影C#
和 Swift 相似不要陷入語言的語法細節,剝離掉語法糖。學習新語言,能夠暫時忽略掉語法的細節, 切換到上帝視角瀏覽器
基於原有的認知,橫向進行比較。正常來講編程語言 80% 概念或範式是通用的,這就是爲何你熟悉一門語言,能夠快速入門其餘語言。服務器
打破認知。另外 20% 包含該門語言獨有的特性和思想, 這纔是咱們須要關注的核心。網絡
下面是常見編程語言的構成圖譜,對照一下,這些概念是否都知道? 是否真的瞭解你用來吃飯的傢伙?併發
沒看懂?看來你沒學過一門真正(複雜)的語言,如 Scala
、C嘎嘎
,Rust
。😺 翻過這些大山,其餘的就是一覽衆山小了。太難了異步
小孩子才作選擇,牛逼(有精力)的人是全都要。你也能夠學幾門比較有表明性語言。參考《七天七語言》開始點技能樹:
按市場劃分:
按範式劃分:
其餘劃分方式:
上文說了,80% 的知識是能夠複用的,咱們要針對另外 20% 該語言獨有的特性和思想進行刻意學習。我這裏介紹一個方法是創建一個標籤雲。這個標籤雲是對這門語言的一些關鍵描述。 例如它的主要特性、優勢、吐槽點。
這些關鍵描述對咱們快速瞭解一門語言有很大的幫助, 這個標籤雲其實表明的就是你對這門語言的基本印象。 換句話說,你學了一門語言,但沒怎麼用,過一段時間就忘光了全部語法細節,可是這門語言的基本印象會長久停留在你腦海中。我想這些印象就是這門語言的精髓所在吧!
那麼怎麼收集這個標籤雲?
隨便舉幾個例子。 Dart 語言:
標籤雲使用 WordClouds 生成
Go 語言:
Javascript:
Elixir:
接着帶着這些問題針對性地去學習這門語言, 這裏以Dart 爲例,由於這兩天正好在學 Dart,準備入坑 Flutter,我本身對 Dart 沒什麼好感。
學習方法, 永遠是 What / Why / How: 是什麼,爲何這麼設計,具體怎麼作?
沒有 Flutter 這門語言確實要掛了。編程語言也要看爹
這是官方本身的定位。
針對客戶端優化主要體如今開發體驗
和運行性能
上面
JIT
(Just in Time) 快速編譯生效,這是 Hot reload 基礎。Hot reload 可讓 Flutter 接近 Web 的開發體驗AOT
(Ahead of Time) 生成高效原生代碼。能夠獲得更快的運行速度和啓動速度語法和 Java 很像,有一些語法糖挺甜的。
沒有關鍵字區分 class 和 interface,能夠說 class 就是 interface
Mixins
。前端對 Mixin 的概念應該都不陌生,畢竟這麼多人用 Vue?
操做符重載。Javascript 不支持操做符重載。因此對前端來講算是一個新東西。 不過我的不推薦,JavaScript 沒有操做符重載不也用得挺爽? 並且操做符的語義不明確,會徒增心智負擔,這時候還不如使用定義良好的方法。有意義的名稱比符號要好記憶。
new
可選。在某些場景讓代碼更簡潔,好比 Flutter 組件聲明。算是彌補沒有 JSX 之痛吧。
void main() {
runApp(
Center(
child: Text(
'Hello, world!',
textDirection: TextDirection.ltr,
),
),
);
}
複製代碼
Callable Classes
。語法糖,沒想到有什麼應用場景。
class WannabeFunction {
call(String a, String b, String c) => '$a $b $c!';
}
var wf = new WannabeFunction();
var out = wf("Hi","there,","gang"); // 🍬
複製代碼
我直接 wf.call
也不麻煩吧? 靈感來自JavaScript? JavaScript 的函數也是一個對象,能夠有本身屬性
Dart 也有一些有趣的操做符/表達式,來看看有多甜:
級聯操做符(Cascade Notation)。級聯操做符是一個很甜的語法糖。不說廢話,看代碼:
querySelector('#confirm') // Get an object.
..text = 'Confirm' // 🍬 甜點,這是類 jQuery 的串行調用的加強版
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
複製代碼
等價於:
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
複製代碼
容器操做符(Collection Operators)。這個語法糖也會比較甜,前期用 Dart 來描述 Flutter 的視圖是一件很痛苦的事情。Dart 陸續添加了一些甜點,如展開操做符
、Collection if/for
, 再加上命名函數參數
和 new可選
,表達力已經很接近 JSX 了
[0, ...list];
[0, ...?list]; // 支持識別null的展開操做符
// collection if
var nav = [
'Home',
'Furniture',
'Plants',
if (promoActive) 'Outlet'
];
// collection for
var listOfStrings = [
'#0',
for (var i in listOfInts) '#$i'
];
複製代碼
在 dart 中 const/final 使用的地方很是多,能夠用於修飾變量、實例變量、對象建立。
注意:靜態數據和不可變數據是不一樣的概念
final name = 'Bob';
const bar = 100000;
const foo = [];
const baz = [];
console.log(foo == baz); // true 編譯時常量
複製代碼
const 將被視爲'編譯時'常量。相對final 有所優化
var foo = const [];
複製代碼
const 修飾變量建立,Dart 會默認以 const 的上下文來實例化對象:
const primaryColors = [
Color("red", [255, 0, 0]),
Color("green", [0, 255, 0]),
Color("blue", [0, 0, 255]),
];
複製代碼
primaryColor被修飾 const 修飾,那麼其下的對象建立都隱式使用 const 修飾。上面的代碼等價於:
const primaryColors = const [
const Color("red", const [255, 0, 0]),
const Color("green", const [0, 255, 0]),
const Color("blue", const [0, 0, 255]),
];
複製代碼
Dart 內置的容器對象默認支持const。 對於自定義類,須要類提供const構造方法, 並且全部實例都必須使用final修飾。
class ImmutablePoint {
static final ImmutablePoint origin =
const ImmutablePoint(0, 0);
// 全部實例變量都必須用final修飾
final num x, y;
// const 構造方法
const ImmutablePoint(this.x, this.y);
}
複製代碼
名義類型。沒有Duck Duck Duck 🦆🦆🦆
Sound Type System(soundness,嚴格類型系統)。即靜態類型+運行時檢查, 好比一個變量靜態類型爲 String,若是將int賦值給它,編譯器會報錯。可是經過某些手段,咱們能夠繞過編譯器檢查,例如強制類型轉換。Sound Type System 能夠在運行時進行類型檢查,不會放過這些錯誤。
main(List<String> args) {
int a;
a = "1" as int; // 繞過了靜態類型檢查, 可是運行會報錯
}
複製代碼
好處:
dynamic:能夠視做是any類型吧?儘可能避免使用
Future/Stream、async/await、Generator。沒必要多說,熟悉 JavaScript 一看就懂
MetaData。和Java的註解差很少。顧名思義,MetaData就是給你的代碼提供更多的信息。能夠用於提示編譯器,在運行時經過反射庫也能夠獲取到MetaData信息。
class SmartTelevision extends Television {
@override
void turnOn() {...}
// ···
}
複製代碼
noSuchMethod()
。相似於 Ruby 的 method_missing。 當未找到屬性或者方法時被調用,能夠實現一些動態屬性或方法。元編程神器。在 JavaScript 中能夠經過Proxy 實現相同的效果。
說實話,Dart 沒有什麼多少讓人眼前一亮的特性。在它身上你能夠看到許多其餘語言的影子、例如Java、JavaScript、Swift... 這也無可厚非,現代編程語言確實長得愈來愈像。
好處是它特別容易上手,壞處是除了 Flutter 綁定以外,我找不到其餘能夠用它的理由。
藉助已有的經驗,很快就能夠入門,這時候能立刻上手去寫是最好的。
能夠從Hello World 開始, 或者也能夠從官方的入門教程開始。Dart 的話。
hello world !
void main(List<String> args) {
print('Hello, World!');
}
複製代碼
經過最簡單的 hello world 也能夠獲知一些關鍵信息:
dart:core
這個包是全局的Flutter 搞起來!
若是你喜歡這門語言,想要讓大家的關係進一步發展,你就要深刻了解它:
編程語言也有三重境界:
看山是山,看山不是山,看山仍是山
只要能解決咱們須要解決的問題,編程語言歷來不是門檻,或者說它是最容易被克服的問題。就像別人吐槽 Flutter 用 Dart 而不用JavaScript同樣。