40分鐘快速入門Dart基礎(上)

教你們快速學習一門新語言:

  • 第一是零基礎:那咱們只能靠本身腳踏實地的多寫多想慢慢熟悉你所選擇的語言 ,沒有別的辦法。(可是dart確實目前爲止最好學的沒有之一的語言)
  • 第二是有基礎:小夥伴們如何快速學習一門新語言,其實很簡單,咱們能夠根據咱們當前所掌握或者熟悉的語言對比,好比:js、java、swift等等任意一門均可以,那麼剩下來咱們只須要掌握與之不一樣的語法,而後在靠本身多寫多想慢慢熟悉。

1、開篇(請記住並瞭解這些萬能的規則)

  • 一切變量皆是對象,每一個對象都是類的實例。int、double、函數、 null 等都是對象,全部對象都繼承自 Object 類
  • Dart可基於AOT(Ahead Of Time)編譯,即編譯成平臺的本地代碼,運行性能高。
  • Dart也可基於JIT(Just In Time)編譯,編譯快速,可熱加載,使開發週期加倍提高(Flutter亞秒級有狀態熱重載)
  • Dart能夠更輕鬆地建立以60fps運行的流暢動畫和轉場。Dart在沒有鎖的狀況下進行對象分配和垃圾回收
  • Dart語法結合Java與JavaScript語法特色,幾乎沒有使人不適的怪異語法,使Java程序員倍感親切,快速上手
  • Dart 沒有關於 public、protected、private 的關鍵字。經過爲變量標識符添加下劃線前綴,代表該標識符對其庫是私有的
  • Dart支持頂級函數、靜態函數、實例函數,也容許在函數中嵌套函數,即局部函數。相似的,dart 也支持頂級變量、靜態變量和實例變量
  • Dart 是強類型語言,但因爲具有類型推導功能因此類型聲明是可選的

2、Dart快速入門基礎目錄:

本文分三節講解:

章節 介紹
上: 主要針對變量、內置類型、操做符、分支與循環講解
中: 主要講解方法、類
下: 主要講解餘下的和一些開發技巧補充

3、開發工具選擇

編譯器主要採用Android Studio編譯器

同時按照國際慣例使用Dart完成一個:"Hello,World!" 並輸入運行結果:java

import 'dart:core';

void main() {
  print('Hello,World');
}
複製代碼

4、變量

Dart中定義變量有兩種方式:程序員

  • 1、靜態類型語言經常使用的方式,顯式指定變量類型。
  • 2、動態語言的經常使用方式,不指定類型,由vm自動推斷。

一切變量皆是對象,每一個對象都是類的實例。int、double、函數、 null 等都是對象,全部對象都繼承自 Object 類。下面咱們看看如何聲明變量:編程

變量是一個引用,未初始化的變量值是Null以下。swift

import 'dart:core';

void main() {
 String name;
 print('$name'); //輸出爲null
}
複製代碼

上面咱們提到了顯示指定變量類型以下:數組

import 'dart:core';

void main() {
 String name ="黃藥師";
 int age =10;
 print('$name''----$age'); //輸出:黃藥師----10
}
複製代碼

動態語言的經常使用方式,不指定類型,由vm自動推斷。安全

import 'dart:core';

void main() {
 String name ="黃藥師";
 name  ='周伯通';
 print('$name'); //輸出:周伯通
}
複製代碼

Dart 語言是強類型語言,沒法將一個已聲明具體變量類型的變量賦值爲另外一個無繼承關係的變量markdown

import 'dart:core';

void main() {
 String name ="黃藥師";
 name  =10;
 print('$name');
}
複製代碼

這種賦值的時候就會報錯:編程語言

import 'dart:core';

void main() {
 int age =10;
 age  =10.0; //這種在賦值的時候就已經報錯
 print('$age');
}
複製代碼

可是這個地方有個須要注意的地方就是int 和double 類都是num的子類以下面寫法是合法。ide

import 'dart:core';

void main() {
 num age =10;
 age  =10.0; //這種在賦值合法
 print('$age');
}
複製代碼

一、var(官方風格指南建議使用var)

var:在聲明變量在賦值的那一刻,就已經決定了它是什麼類型。函數

上面這句話是什麼意思尼?其實很簡單:

import 'dart:core';

void main() {
  //age 已經肯定爲num類型併爲其賦值18歲,若是你賦值字符串,那麼就會報錯
 var age =18;
 age  ='18';
 print('$age');
}
複製代碼
import 'dart:core';

void main() {
  //age 已經肯定爲num類型並可是沒有爲其賦值,若是你賦值字符串那麼是正確
 var age;
 age  =18;
 age ='18';
 print('$age');
}
複製代碼

二、Object

一切變量皆是對象,每一個對象都是類的實例。int、double、函數、 null 等都是對象,全部對象都繼承自 Object 類

import 'dart:core';
void main() {
 Object age ='18';
 age  =18;
 print('$age');
}
複製代碼

三、dynamic

dynamic相似java中的Object ,因此聲明的變量行爲與Object同樣,使用也是同樣,可是咱們須要知道的是:dynamic不是在編譯時肯定類型的,而是在運行時:這句話有點懵,究竟是什麼意思呢?

import 'dart:core';

void main() {
  dynamic name ='黃藥師';
  print(name.runtimeType); //輸入:String
  name =18;
  print(name.runtimeType); //輸入:int
}
複製代碼

說明:

在聲明變量的時候,也能夠選擇加上具體 類型:String name = 「黃藥師」

沒有初始化的變量自動獲取一個默認值爲 null(類型爲數字的 變量如何沒有初始化其值也是 null)。

對於局部變量,按照dart官方建議使用var來聲明變量

四、final與const

final 和const 從本質上看不出區別:若是你但願一個變量在賦值後其引用不能再改變,能夠經過final或const這兩個關鍵字來實現。

  • final是運行時常量,final的要求是其聲明的變量在賦值之後是不能在改變:

final有兩種使用場景

  • 類中的變量聲明,必須在聲明時賦值。
  • 類中的成員變量聲明,能夠在聲明時候賦值,也能夠經過構造函數賦值如:
import 'package:flutter/cupertino.dart';

class TestDart extends StatefulWidget{

  final String name;

  TestDart(this.name);

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return null;
  }
}

class TestDartState extends State<TestDart>{

  final String  URL_NAME ="https://wwww.baidu.com";

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return null;
  }

}
複製代碼

const是編譯期常量。這裏關鍵點區分什麼是編譯時常量,說白了就是其定義的值必須是一個字面常量值以下圖:

針對final 和const 理解的有點模糊的能夠參考這篇文章: 能夠參考這裏Flutter 知識梳理(Dart)-Dart中static final const 區別

5、操做符:

Dart中的操做符與面嚮對象語言中(如:java)操做符絕大多數是相同。該有的都有,不應有的Dart也有 。

操做符 說明
+
_
*
/
% 取模運算 元
~/ 整除
=> 箭頭函數
import 'dart:core';

void main() {
  var i = 6;
  var r = 2;

  //加法:
  print('${i + r}'); //輸出:8
  //減法
  print('${i - r}'); //輸出:4
  //乘法
  print('${i * r}'); //輸出:12
  //除法
  print('${i / r}'); //輸出:3.0
  //取模運算
  print('${i % r}'); //輸出:0
  //整除
  print('${i ~/ r}'); //輸出:3
}
複製代碼
  • 類型判斷操做符

as類型轉換is若是對象是指定的類型返回 Trueis!若是對象是指定的類型返回 False

注意點:as 操做符把對象轉換爲特定的類型,可是若是沒法完成轉換則會拋出一個異常

import 'dart:core';

void main() {
  var name = "黃藥師";

  if (name is String) {
    //判斷條件爲 true
    print("name is String");
  }
  var age = 1;
  if (age is! String) {
    //判斷條件爲 true
    print("age is String");
  }
  
  //說明:因爲age 是int 類型 不是一個String類型,因此活報以下錯誤
  //'int' is not a subtype of type 'String' in type cast
  String newResult = age as String;
}
複製代碼
  • 賦值操做符
操做符 說明
= 賦值操做符
+= 加和賦值操做符
-= 減和賦值操做符
*= 乘和賦值操做符
%= 取模和賦值操做符
/= 除和賦值操做符
??= 值爲null的變量值
import 'dart:core';

void main() {
   var age =20;
   //加和賦值操做符
   print('${age+=10}');
   //減和賦值操做符
   print('${age-=10}');
   //乘和賦值操做符
   print('${age*=10}');
   //除和賦值操做符
   double newAge =20.0;
   print('${newAge /= 10.0}');
   //取模和賦值操做符
   double price =230.0;
   print('${price %= 10.0}');

   String name;
   name ??= "黃藥師";
   // 若是 name 是 null,則把等於號右邊的值 賦值給 name;
   // 若是不是 null,則 name 的值保持不變
    print("$name"); //輸出:黃藥師
}
複製代碼
  • 替代條件表達式操做符

在Dart中有兩種特殊操做符能夠替代 if-else 語句

  • 三目運算符
  • ??
import 'dart:core';

void main() {
  var age = 10;
  print(printAge1(age));
  print(printAge2(age));
  print(printAge3(age));
}

//if-else
printAge1(age) {
  if (age == 10) {
    return age;
  }
  return age;

  //輸出:10
}

//第一種替換if-else 使用三目運算符
printAge2(int age) {
  return age == 10 ? age : 0; //輸出:10
}

//第二種用"??"替換if-else
printAge3(int age) {
  return age == 10 ?? 0; //輸出:true
}

複製代碼
  • 級聯操做符

級聯操做符 (..) 能夠在同一個對象上 連續調用多個函數以及訪問成員變量。 使用級聯操做符能夠避免建立 臨時變量, 而且寫出來的代碼看起來 更加流暢:

import 'dart:core';

void main() {
  var  list = List();
  print("${list..add("黃藥師")..add("郭靖")}"); //輸出:黃藥師,郭靖
}
複製代碼
  • 安全操做符

Dart提供了 ?.操做符。左邊的操做對象 若是 爲 null 則返回 null

import 'dart:core';
void main() {
  String name;
  //沒有添加"?"空指針
  print(name.length); // The getter 'length' was called on null.
  //添加"?"
  print(name?.length); //輸出null
}
複製代碼

6、內置類型:

一、num(數值)

dart的num類型有量兩種分別是int 和double兩種,這兩種都是num的子類。

void main() {
  var age = 18;
  print(age.runtimeType); //輸出 int

  var price = 8.0;
  print(price.runtimeType); //輸出:double

  num year = 2020;
  print(year.runtimeType); //輸出:int

  year = 2020.0;
  print(year.runtimeType); //輸出:double

  int days = 10;
  print(days.runtimeType); //輸出:int

  double limit = 8.90;
  print(limit.runtimeType); //輸出:double
}
複製代碼

同時num也支持一些數據類型的轉換:

void main() {
  var age = '18';
  print(age.runtimeType); //輸出:String 類型

  int parseAge = int.parse(age);
  print(parseAge.runtimeType); //輸出:int 類型
}
複製代碼

二、string(字符串)

Dart字符串是UTF-16編碼的字符序列,可使用單引號或者雙引號來建立字符串,單引號和雙引號能夠嵌套使用,不然須要使用\進行轉義。字符串中也能夠引用變量與表達式,同時能夠實現字符串拼接功能

import 'dart:core';

void main() {
  var name = '黃藥師';
  print(name.runtimeType); //輸出:String 類型

  var newName1 = "my name is $name";
  print(newName1); //輸出:my name is 黃藥師

  //和上面反之,須要添加上{}
  var nameName2 = "my name is ${User().name}";
  print(nameName2); //輸出:my name is 黃藥師
}

class User {
  var age =10;
  var name ="黃藥師";
}
複製代碼

提供一個 r 前綴能夠建立一個 「原始 raw」 字符串,說白了就是不須要轉義(若是添加上轉義字符那麼將會失效)以下:

import 'dart:core';

void main() {
  //r:不須要轉義
  print(r"換行符: \n"); //輸出:換行符:\n
  print("換行符: \\n"); //輸出:換行符:\n
}
複製代碼

三、bool(布爾值)

Dart有個類型名字爲bool 類型,而在Dart中只有兩個對象是布爾類型:分別是true和false。在Dart中還強類型檢查,只有當爲true的時候纔會真。

import 'dart:core';

void main() {
 bool isLoading;
 print('$isLoading'); //輸出:null;
 
 isLoading =true;
 print('$isLoading'); //輸出:true;
}
複製代碼

四、list(數組)

幾乎全部的編程語言中數組是必不可少的,而在Dart中 list 也是必不可少的。

下面咱們來看一下List一些基本用法:

  • 初始化
import 'dart:core';

void main() {
  var names = List();
  print(names.length); //輸出:0;

  var names1 = List(2);
  print(names1.length); //輸出:2;
  
  //若是想要爲 List 添加不一樣數據類型的變量,則須要直接只買數據類型爲Object
  var names2 = List<Object>();
  names2.add('黃藥師');
  print(names2.runtimeType); //輸出:List<Object> 類型
  
  //直接複製,能夠添加不一樣類型
  var names3 = ['黃藥師',12,11.0];
  print(names3.length); //輸出:3
  
  //在list 字面上以前添加const 關鍵字,能夠定義一個不變的list對象(編譯是常量)
  var names4 = const[1,2,3];
  print(names4.length); //輸出:3
  ///若是爲names4集合添加一個值以下操做,這種操做是錯誤,list不可變
  ///報錯:Cannot add to an unmodifiable list
  names4.add(4);
}
複製代碼
  • 經常使用屬性和方法
import 'dart:core';

import 'package:myfirstflutter/test/user.dart';

void main() {
  var names1 = [1, 2, 3];
  print(names1.length); //輸出:0;

  //排序
  List<User> myList = [User('黃藥師', 23), User('歐陽鋒', 61), User('楊過', 48)];
  myList.sort((a, b) => (b.age).compareTo(a.age));

  //集合循環
  myList.forEach((v) {
    print('${v.name}${v.age}'); //輸出:歐陽鋒61,楊過48,黃藥師23
  });

  //查找符合條件
  var result = myList.where((v) => v.age == 23);
  result.forEach((v){
    //isEmpty屬性,返回列表是否爲空
    print('${v.name}${v.age}');
  });
  //isEmpty屬性,返回列表是否爲空
  print(myList.isEmpty);

  //isNotEmpty屬性,返回列表是否有元素
  print(myList.isNotEmpty);
  
  //獲取List中的第一個元素
  print("獲取List中第一個元素${names1.first}");
}
複製代碼
  • 添加數據
import 'dart:core';

void main() {
  var names1 = ['楊過', '小龍女', '黃蓉'];
  //添加數據
  names1.add('丘處機');
  print(names1.length); //輸出:4;

  var names2 = List(2);

  ///當執行add 時候會報錯:Cannot add to a fixed-length list
  ///(固定長度的list是不能經過add添加數據)
  ///names2.add(1);

  //固定長度的list使用一下方式能夠設置數據
  names2[0] = '黃藥師';
  names2[1] = '歐陽鋒';
  names2.forEach((v) {
    print('$v'); //輸出:黃藥師 歐陽鋒
  });

  var names3 = ['楊過', '小龍女', '黃蓉'];
  var names4 = ['1', '2', '3'];
  //添加所有元素
  names3.addAll(names4);
  names3.forEach((v) {
    print('$v'); //輸出:楊過 小龍女 黃蓉 1 2 3
  });
}
複製代碼
  • 刪除數據
import 'dart:core';

void main() {
  var names1 = ['楊過', '小龍女', '黃蓉', '丘處機', '黃藥師'];
  //刪除指定元素
  names1.remove('楊過');
  print(names1); //輸出:小龍女 黃蓉 丘處機 黃藥師

  //刪除最後一個元素
  names1.removeLast();
  print(names1); //輸出:小龍女 黃蓉 丘處機

  //刪除指定位置元素
  names1.removeAt(names1.length - 1);
  print(names1); //輸出:小龍女 黃蓉

  //刪除指定位區域元素
  names1.removeRange(0, 1);
  print(names1); //輸出 黃蓉

  //下面這個方法是將列表List中的toString只有的字符串的長度等於3的元素所有刪除
  names1.removeWhere((item) =>item.toString().length==3);
  print('刪除列表中toString後長度爲3的元素:==>$names1');
}

複製代碼

以上還少「改」和「查」 其實這些在上面的例子代碼中已經存在了一些,這裏留個你們一個練習題:能夠自行把「改」和「查」本身總結一下

五、Map(集合)

Map和lList同樣基本上只要學習開發語言map也是必不可少的一部分,Map是鍵值對相關的對象。 鍵和值能夠是任何類型的對象。每一個鍵只出現一次, 而一個值則能夠出現屢次。

import 'dart:core';

void main() {
  //直接聲明,用{}表示。裏面寫key和value 每組鍵值對中間用逗號隔開
  var names = {'name1': '黃藥師', 'name2': '楊過', 'name3': '老頑童'};
  print(names); //輸出:{name1:黃藥師,name2: 楊過, name3:老頑童}

  var names1 = Map();
  names1['name1'] = '黃蓉';
  names1['name2'] = '黃藥師';
  names1['name3'] = '郭靖';
  print(names1); //{'name1': '黃蓉', 'name2': '黃藥師', 'name3': '郭靖'};

  //限定Map 能夠存儲的數據類型
  var names2 = <String, String>{'name': '黃藥師'};
  print(names2); //輸出:{'name':'黃藥師'}

  //與list List相似,要建立一個編譯時常量的Map須要在Map的字面量前加上const 關鍵字
  var names3 = const {'name': '黃藥師', 'age': 60};
  print(names3); //輸出:{'name':'黃藥師','age' : 60}

  //循環
  names1.forEach((k, v) {
    print(v); //輸出:黃蓉,黃藥師。郭靖
  });

  //查詢刪除
  var names4 = {'name1': '黃藥師', 'name2': '楊過', 'name3': '老頑童'};
  names4.removeWhere((k, v) => k == 'name1');

  names4.forEach((k, v) {
    print(v); //輸出:楊過,老頑童
  });

  //根據指定key 進行刪除
  names4.remove('name1');
  //找找是否包含指定key
  names4.containsKey('name2');

  //找找是否包含指定value
  names4.containsValue('老頑童');

  //添加一個Map對象
  names4.addAll({'name': '丘處機'});
}
複製代碼

Map和List同樣,一樣有增刪改查功能

7、分支與循環:

分支 Dart分支目前有if-else 和switch兩種

  • if條件分支:
import 'dart:core';

void main() {
  var age = 18;
  if (age < 0) {
    print('age < 0');
  } else if (age == 0) {
    print('age = 0');
  } else {
    print('age > 0');
  }
}
複製代碼
  • switch條件分支:
import 'dart:core';

void main() {
  // 在switch的case中可使用整數、字符串、枚舉類型和編譯時常量
  String name = '黃藥師';
  switch (name) {
    case '郭靖':
      break;
    case '老頑童':
      break;
    default:
      print('Default');
  }
}
複製代碼

Dart中循環支持 for、while 以及 do-while 三種。

import 'dart:core';

void main() {
  // for循環
  for (int i = 0; i < 9; i++) {
    print(i);
  }

  // while循環
  while (true) {
    //do something
  }

  //do-while循環
  do {
    //do something
  } while (true);
}
複製代碼

可是在Dart 還有一些特有的系統循環函數

import 'dart:core';

void main() {
  var names = ["張無忌", "小龍女", "趙敏"];
  // for...in...循環,是加強for
  for (var it in names) {
    print(it); // 輸出:"張無忌","小龍女","趙敏"
  }

  //forEach循環。其參數爲一個Function對象,這裏傳入一個匿名函數
  names.forEach((v) {
    print(v); // 輸出:"張無忌","小龍女","趙敏"
  });

  names.forEach((v) => print(v)); //輸出:"張無忌","小龍女","趙敏"
}

複製代碼

咱們在來看一下在Dart中怎麼去對一組Map數據進行循環

import 'dart:core';

void main() {
  var myMap = {'name': '黃藥師', 'age': '50', 'skills': '彈指神通'};
  //forEach遍歷Map
  myMap.forEach(
      (k, v) => print("$k : $v")); //輸出:name : 黃藥師 age : 50 skills : 彈指神通

  //根據鍵獲取值來遍歷。經過keys返回Map中全部鍵的集合
  for (var k in myMap.keys) {
    print("$k : ${myMap[k]}");//輸出:name : 黃藥師 age : 50 skills : 彈指神通
  }
}
複製代碼

總結:

看是否是超級好上手,好操做~其實Dart的整個學習起來仍是蠻簡單的,對於有基礎的老司機更簡單一些。分分鐘敲起來~

這篇文章就簡單的介紹到這裏如何短期快速入門Dart,避免入坑。因爲是想讓你們快速入門Flutter,因此針對上面的這些章節咱們講解的只是一些在開發Flutter 過程當中經常使用的一些方法和函數。若是要想對Dart有更深的瞭解和學習,後期能夠關注我哦,若有問題能夠直接在下方留言。

感受不錯能夠點贊加關注,我會持續輸出優質的文章。

最後附上:知乎 如何快速掌握Dart這門語言並進階Flutter變成大神

下一篇: 40分鐘快速入門Dart基礎(中)

相關文章
相關標籤/搜索