1. 程式人生 > >Dart學習之基礎語法

Dart學習之基礎語法

承接上一篇我們搭建了Dart環境,這一篇我們將學習Dart的基礎語法。

                                            

Dart的所有東西都是物件,包括數字,函式等。

它們都繼承自Object,預設是都是null(包括數字),所以數字,字串都可以呼叫各種方法。

一、Dart中的關鍵字(56個)

33個保留字(不能使用保留字作為識別符號)

關鍵字---
ifsuperdoswitchassert
elseinthisenum
isthrowtruebreak
newtrycaseextends
nulltypedefcatchvar
classfalsevoidconst
finalrethrowwhilecontinue
finallyreturnwithfor
default

內建標誌符有:(17個)

關鍵字---
abstractdeferredasdynamic
covariantexportexternalfactory
getimplementsimportlibrary
operatorpartsetstatic
typedef

Dart2相對於Dart1新增的,支援非同步功能的關鍵字有:(6個)

關鍵字---
asyncasync*awaitsync*
yieldyield*

跟java相比,Dart特有的關鍵字有:(25個)

關鍵字---
deferredasassertdynamic
sync*asyncasync*in
isawaitexportlibrary
externaltypedeffactoryoperator
varpartconstrethrow
covariantsetyieldget
yield*

二、變數和常量

(一)變數的宣告,可以使用 var、Object 或 dynamic 關鍵字。

建立變數並初始化變數例項:

//Dart語言本質上市動態型別語言,型別是可選的
//可以使用var宣告變數,也可以使用型別(比如String)來直接宣告變數
//一個變數也可以被賦予不同型別的物件
//但是大多數情況,我們不會去改變一個變數的型別

//字串賦值的時候,可以使用單引號,也可以使用雙引號。
var str = "this is string vlaues.";

變數儲存引用。

1.使用Object或dynamic關鍵字

dynamic name = "張三";
呼叫的變數name包含對String值為“張三” 的物件的引用。
name推斷變數的型別是String,但可以通過指定它來更改該型別。

如果物件不限於單一型別(沒有明確的型別),請使用Object或dynamic關鍵字

Object name1 = "小明";
dynamic name2 = "老王";

2.顯式宣告將被推斷的型別,比如String,int等。

//可以使用String顯示宣告字串型別
String str1 = "dart str";

(二)預設值

未初始化的變數的初始值為null(包括數字),因此數字、字串都可以呼叫各種方法,這個我們上面有提到。

//我們先宣告一個int型別的變數
int intDefaultValue;
//assert 是語言內建的斷言函式,僅在檢查模式下有效
//在開發過程中,除非條件為真,否則會引發異常。(斷言失敗則程式立即終止)
assert(intDefaultValue == null);
//列印結果為null, 說明數字型別初始化值為null
print(intDefaultValue);

(三)Final and const

如果您從未打算更改一個變數,那麼使用 final 或 const,不是var,也不是一個型別。
一個 final 變數只能被設定一次;const 變數是一個編譯時常量。(Const變數是隱式的final。)

final的頂級或類變數在第一次使用時被初始化。

1.被final或者const修飾的變數,變數型別可以省略。

//可以省略int型別的宣告
final test = 111;
//等同於上面
final int test = 111;

2.被 final 或 const 修飾的變數無法再去修改其值。

//被final修飾的變數的值無法被改變
final test1 = "test";
//這樣寫會提示'test1', a final variable, can only be set once
test1 = "test1";
  
//被const修飾的變數不能被重新賦值
const test2 = 20.02;
//這樣寫會提示 Constant variables can't be assigned a value
test2 = 23.33;

3.注意:flnal 或者 const 不能和 var 同時使用

//會提示:Expected an identifier,
//因為var是用來修飾變數的,而final修飾的變數稱之為常量(不能改變,只能賦值一次),所以不能這麼混合使用吧(我是這麼理解的)
final var test3 = true;

//這一句提示這個:The const variable 'var' must be initialized   
//The name 'var' is already defined.
const var test4 = 'test4';

4.常量如果是類級別的,請使用 static const

class Test{
  static const name = "test";

  static main(){
    //這裡會報錯:Undefined name 'static'
    //static型別的變數是屬於類的所以在類裡面,方法之外
    static const name = "test";
  }
}

5.常量的運算

final speed = 200;//(km/h)
final double distance = 2.5 * speed; // 距離 = 速度 * 時間
  
const speed1 = 200;
const double distance1 = 2.5 * speed1;

6.const關鍵字不只是宣告常數變數。也可以使用它來建立常量值,以及宣告建立常量值的建構函式。 任何變數都可以有一個常量值。

//注意:[] 建立的是一個空的list集合
// const[] 建立一個空的、不可變的列表(EIL)
var varList = const [];     //varList 當前時一個EIL
final finalList = const []; //finalList一直是EIL
const constList = const []; //constList是一個編譯時常量的EIL

//可以更改非final、非const變數的值
//即使它曾經具有const值也可以改變
varList = [111, 222, 333];

// 不能更改final變數或const變數的值
// 這樣寫,編譯器提示:a final variable, can only be set once
// finalList = [];
// 這樣寫,編譯器提示:Constant variables can't be assigned a value
// constList = [];

7.只要任何插值表示式是一個計算結果為null或數字,字串或布林值的編譯時常量,那麼文字字串就是編譯時常量。(關於$表示式和不同的資料型別後面會講解。)

//這些是常量字串
const aConstNum = 0;
const aConstBool = true;
const aConstString = 'a const string';

//這些不是常量字串
var aNum = 0;
var aBool = true;
var aString = 'a string';

//編譯通過
const validConstString = '$aConstNum $aConstBool $aConstString';
var validString = '$aNum $aBool $aString';
var invalidString = '$aNum $aBool $aConstString';
  
//編譯器報錯
//報錯:Const variables must be initialized with a constant value
//const常量必須用const型別的值初始化
const invalidConstString = '$aConstNum $aConstBool $aNum';

8.到這裡final 和 const我們就介紹完畢了,那麼相信有些人肯定會有疑問,final 和 const到底有什麼區別呢?帶著這個疑問我們先看下面這段程式碼。

//編譯器通過
var a = 1;
final f = 3;
const d = 2;
final b = a;
const c = d;
//編譯器報錯
//報錯:Const variables must be initialized with a constant value
const e = a;
const g = f;

從上面程式碼我們可以看出,final 和 const的一個區別:

final 要求變數只能初始化一次,並不要求賦的值一定是編譯時常量,可以是常量也可以不是。而 const 要求在宣告時初始化,並且賦值必需為編譯時常量。

第二個區別是它們初始化的時機不同:

final 是惰性初始化,即在執行時第一次使用前才初始化。而 const 是在編譯時就確定值了。    

                                                    

三、特殊資料型別

Dart中支援以下特殊型別:

numbers 數字
strings 字串
booleans 布林
lists (also known as arrays) list集合(也稱為陣列)
maps map集合
runes (for expressing Unicode characters in a string) 字元(用於在字串中表示Unicode字元)
symbols 符號

(一)num 數字型別

num是數字型別的父類,有兩個子類 int 和 double。
num型別包括基本的運算子,如+,-,/和*,位運算子,如>>,在int類中定義。

如果num和它的子類沒有你要找的東西,math庫可能會找到。比如你會發現abs(),ceil()和floor()等方法。

1.int型別

int表示整數,int的取值不大於64位,具體取決於平臺。在Dart VM上,值可以從 -2的63次方 到 2的63次方減1.

整數是沒有小數點的數字。示例如下:

int intNum1 = 10 ;
print(intNum1);
int intNum2 = 0xDEADBEEF ;
print(intNum2);

2.double型別

64位(雙精度)浮點數,如IEEE 754標準所規定。

如果一個數字包含一個小數,那麼它就是一個double型別。示例如下:

double doubleNum1 = 1.1;
print(doubleNum1);
double doubleNum2 = 1.42e5;
print(doubleNum2);

3.String型別

Dart裡面的String是一系列 UTF-16程式碼單元。

(1)可以使用單引號或雙引號來建立一個字串。

String str1 = '單引號基本使用demo.';
String str2 = "雙引號基本使用demo.";

(2)單引號或者雙引號裡面巢狀使用引號。

//單引號裡面巢狀單引號,必須在前面加反斜槓
String str3 = '雙引號裡面有單引號it\'s,必須在前面加反斜槓.';
//雙引號裡面巢狀單引號(正常使用)
String str4 = "雙引號裡面有單引號it's.";
//單引號裡面巢狀雙引號(正常使用)
String str5 = '單引號裡面有雙引號,程式設計開發初學必備語句"hello world"';
//雙引號裡面巢狀雙引號,必須在前面加反斜槓
String str6 = "雙引號裡面有雙引號,程式設計開發初學必備語句\"hello world\"";

(3)多個字串相鄰中間的空格問題:

經測試發現,除了單引號巢狀單引號或者雙引號巢狀雙引號不允許出現空串之外,其餘的幾種情況都是可以執行的。

示例如下:

// 這個會報錯
//String blankStr1 = 'hello''''world';
// 這兩個執行正常
String blankStr2 = 'hello'' ''world'; //結果: hello world
String blankStr3 = 'hello''_''world'; //結果: hello_world

// 這個會報錯
//String blankStr4 = "hello""""world";
// 這兩個執行正常
String blankStr5 = "hello"" ""world"; //結果: hello world
String blankStr6 = "hello""_""world"; //結果: hello_world

//單引號裡面有雙引號,混合使用執行正常
String blankStr7 = 'hello""""world'; //結果: hello""""world
String blankStr8 = 'hello"" ""world'; //結果: hello"" ""world
String blankStr9 = 'hello""_""world'; //結果: hello""_""world

//雙引號裡面有單引號,混合使用執行正常
String blankStr10 = "hello''''world"; //結果: hello''''world
String blankStr11 = "hello'' ''world"; //結果: hello'' ''world
String blankStr12 = "hello''_''world"; //結果: hello''_''world

(4)可以使用相鄰字串文字或+ 運算子連線字串:

//直接把相鄰字串寫在一起,就可以連線字串了。
String connectionStr1 =  '字串連線'
'甚至可以在'
'換行的時候進行。';

//用+把相鄰字串連線起來。
String connectionStr2 =  '字串連線'
  + '甚至可以在'
  + '換行的時候進行。';

//使用單引號或雙引號的三引號:
String connectionStr3 = ''' 
  你可以建立
  像這樣的多行字串。
  ''' ;

String connectionStr4 = """這也是一個
  多行字串。""";

(5)關於轉義符號的使用

宣告raw字串(字首為r),在字串前加字元“r”,或者在\前面再加一個\,
可以避免“\”的轉義作用,在正則表示式裡特別有用

舉例如下:

print(r"換行符:\n"); //這個結果是 換行符:\n
print("換行符:\\n"); //這個結果是 換行符:\n
print("換行符:\n");  //這個結果是 換行符:
(6)可以使用${表示式}將表示式的值放入字串中。如果表示式是識別符號,則可以跳過{}。

為了獲得對應於object的字串,Dart呼叫object的toString()方法。

String replaceStr1 = '字串連線';
print('$replaceStr1'
    + '甚至可以在換行的時候進行。' == '字串連線'
    + '甚至可以在換行的時候進行。');

String replaceStr2 = 'Android Studio';
print('你知道' +
    '${replaceStr2.toUpperCase()}'
      + '最新版本是多少嗎?' ==
      '你知道ANDROID STUDIO最新版本是多少嗎?');

注:
==操作符測試兩個物件是否相等。如果兩個字串包含相同的程式碼單元序列,那麼它們是等效的。

(三)bool 布林值

為了表示布林值,Dart有一個名為的型別bool。
只有兩個物件具有bool型別:true和false,它們都是編譯時常量。

Dart的型別安全意味著您不能使用if(nonbooleanValue)或assert(nonbooleanValue)等程式碼。

相反,Dart使用的是顯式的檢查值,如下所示:

// 檢查是否為空字串
var fullName = '';
assert(fullName.isEmpty);

// 檢查0
var hitPoints = 0;
assert(hitPoints <= 0);

// 檢查是否為null
var unicorn;
assert(unicorn == null);

// 檢查是否為NaN
var iMeantToDoThis = 0 / 0;
assert(iMeantToDoThis.isNaN);
assert 是語言內建的斷言函式,僅在檢查模式下有效

在開發過程中, 除非條件為真,否則會引發異常。(斷言失敗則程式立刻終止)。

(四)list 集合(也稱為陣列)

幾乎所有程式語言中最常見的集合可能是陣列或有序物件組。
在Dart中,陣列是List物件,因此大多數人只是將它們稱為List。

Dart list文字看起來像JavaScript陣列文字。 以下是一個簡單的Dart列表:

//建立一個int型別的list
List list = [10, 7, 23];
print(list);

要建立一個編譯時常量const的list,示例如下:

List constantList = const[10,3,15];

注意事項:

1.可以直接列印list包括list的元素,list也是一個物件。但是java必須遍歷才能列印list,直接列印是地址值。
2.和java一樣list裡面的元素必須保持型別一致,不一致就會報錯。
3.和java一樣list的角標從0開始。

(五)map集合

一般來說,map是將鍵和值相關聯的物件。鍵和值都可以是任何型別的物件。

每個鍵只出現一次,但你可以多次使用相同的值。Dart支援map由map文字和map型別提供。

注意:

和java一樣,map裡面的元素必須保持型別一致,不一致就會報錯。

(六)runes (for expressing Unicode characters in a string) 字元(用於在字串中表示Unicode字元)

(七)symbols 符號