Flutter開發之Dart的數據類型01

dart-logo

Dart數據類型

Dart內置的數據類型中, 支持如下幾種數據類型html

  • numbers(數字)
  • strings(字符串)
  • booleans(布爾)
  • lists (也被稱之爲 arrays)
  • maps
  • runes (用於在字符串中表示Unicode字符)
  • symbols

上面的數據類型能夠直接使用字面量初始化git

var str = 'this is a string' ;
var isStr = true;
複製代碼

也可使用構造函數初始化, 因爲Dart中每一個變量引用的都是一個對象 – 一個類的實例, 一些內置的類型具備本身的構造函數github

// 可使用 Map()構造函數來建立一個 map,就像這樣 
var map = new Map();
複製代碼

DartNumbers支持兩種類型的數字:正則表達式

  • int: 整數值,其取值一般位於-2^532^53之間, 差很少9*10^16, 也就是支持16位數字
  • double: 64-bit (雙精度) 浮點數,符合IEEE 754標準

int

  • 其取值一般位於-2^532^53之間
  • 也就是-9,007,199,254,740,992和9,007,199,254,740,992之間
  • 實際在編譯中則是超過19位則會報錯
  • 更多可參考問題 1533瞭解更多信息
// 以下定義則會報錯, 定義的int星變量須要在9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808之間
var bil = 12345678901234567890;
複製代碼

一些經常使用的判斷屬性api

const m1 = 12;
  
  // 是否爲負數, 大於0即爲false
  print(m1.isNegative);
  print(0.isNegative);

  // 是不是有限的
  print(b32.isFinite);
  print(m1.isFinite);

  // 是不是無窮大或者無窮小
  print(m1.isInfinite);

  // 是否爲偶數
  print(m1.isEven);

  // 是否爲奇數
  print(m1.isOdd);

  // 是不是NaN值
  print(m1.isNaN);
  
  // 數據的符號,-1.0:值小於0、+1.0:值大於0、-0.0/0.0/NaN:值是其自己
  print(21.sign);  // 1
  print(-23.sign); // -1
  print(0.sign);   // 0
  print(-0.sign);  // 0
複製代碼

int數字類型中經常使用的函數數組

const m3 = 24;
  
  // 獲取絕對值
  print(m3.abs());

  // 轉成字符串
  print(m3.toString());

  // 冪次求模; m3的4次冪, 在對3求模
  print(m3.modPow(4, 3)); // 1

  // 返回m3和16的最大公約數
  print(m3.gcd(16));
  
  // 返回m3除以5的餘數
  print(m3.remainder(5));

  // 轉成double
  print(m3.toDouble());
  
  // 比較大小, 0:相同、1:大於、-1:小於
  print(m3.compareTo(30));
複製代碼

double

下面是定義double的一些方式:安全

var y = 1.1;
var exponents = 1.42e5;
複製代碼

double類型相關的屬性使用bash

// 是不是NaN值
  print(d0.isNaN);
  // 是不是無窮大或者無窮小
  print(d0.isInfinite);
  // 是不是有限的
  print(d0.isFinite);
  // 是否爲負數, 大於0即爲false
  print(d0.isNegative);

  // 根據代碼單元生成的哈希碼
  print(d0.hashCode);
  
  // 數據的符號,-1.0:值小於0、+1.0:值大於0、-0.0/0.0/NaN:值是其自己
  print(d0.sign);
  print(-1.23.sign);
  print(0.0.sign);

  // 返回運行時的類型
  print(d0.runtimeType);  // double
複製代碼

double類型相關方法的使用微信

// 轉成字符串
  print(d0.toString());

  // 取整數, 小數點捨去
  print(d0.toInt());

  // 比較大小, 0:相同、1:大於、-1:小於
  print(d0.compareTo(30));

  // 獲取絕對值
  print(d0.abs());

  // 四捨五入
  print(d0.round()); // 13
  // 向上取整
  print(d0.ceil());  // 14
  // 向下取整
  print(d0.floor()); // 13

  // 輸出的double類型, 至關於d0.round().toDouble()
  print(d0.roundToDouble()); // 13.0
  print(d0.ceilToDouble());  // 14.0
  print(d0.floorToDouble()); // 13.0

  // 保留指定的小數位數(四捨五入), 不足補0, 字符串返回
  print(d0.toStringAsFixed(2)); // 13.10

  // 保留變量的位數(小數點先後的總位數), 不足補0, 多餘的四捨五入
  print(d0.toStringAsPrecision(10));  // 13.09870000

  /** toStringAsExponential * 1.toStringAsExponential(); // 1e+0 * 1.toStringAsExponential(3); // 1.000e+0 * 123456.toStringAsExponential(); // 1.23456e+5 * 123456.toStringAsExponential(3); // 1.235e+5 * 123.toStringAsExponential(0); // 1e+2 */


  /** toStringAsPrecision * 1.toStringAsPrecision(2); // 1.0 * 1e15.toStringAsPrecision(3); // 1.00e+15 * 1234567.toStringAsPrecision(3); // 1.23e+6 * 1234567.toStringAsPrecision(9); // 1234567.00 * 12345678901234567890.toStringAsPrecision(20); // 12345678901234567168 * 12345678901234567890.toStringAsPrecision(14); // 1.2345678901235e+19 * 0.00000012345.toStringAsPrecision(15); // 1.23450000000000e-7 * 0.0000012345.toStringAsPrecision(15); // 0.00000123450000000000 */
複製代碼

Booleans

  • 爲了表明布爾值,Dart有一個名字爲bool的類型。
  • 只有兩個對象是布爾類型的:truefalse 所建立的對象, 這兩個對象也都是編譯時常量
  • Dart須要一個布爾值的時候,只有true對象才被認爲是true, 全部其餘的值都是flase; 像 一、 "aString"、 以及someObject等值都被認爲是false
const m = 1;
  if (m) {
    print('是一個布爾值');
  } else {
    print('不是一個布爾值');
  }
複製代碼
  • Dart中上面判斷語句是合法的代碼
  • 可是在Dart檢查模式運行,上面的代碼將會拋出一個異常,表示m變量不是一個布爾值
  • 因此不建議這麼使用上述方法進行判斷

Strings

Dart字符串是UTF-16編碼的字符序列, 可使用單引號或者雙引號來建立字符串:markdown

var s1 = 'Single quotes work well for string literals.';
var s2 = "Double quotes work just as well.";
// 單引號裏面有單引號(雙引號裏面有雙引號)時, 必須使用反斜\槓轉義
var s3 = 'It\'s easy to escape the string delimiter.';
var s4 = "It's even easier to use the other delimiter.";
複製代碼

字符串的拼接

直接把相鄰字符串寫在一塊兒,就能夠鏈接字符串了

var string = 'name''+''age'
複製代碼

用+把相鄰字符串鏈接起來

var string1 = 'name' + '+' + 'age';
複製代碼

引用變量

  • Dart中使用$符號引用變量或者表達式
  • 表達式引用方式: ${表達式}, 若是表達式是一個變量則{}能夠省略
const num1 = 12;
  // 引用表達式
  const ageStr0 = 'age = $num1';
  const ageStr1 = 'age = ${num1} is my age';
  // 引用表達式
  const ageStr2 = 'age = ${num1 * num1}';
複製代碼

多行字符串

使用單引號或雙引號的三引號

const line1 = ''' 道路千萬條,安全第一條, 行車不規範,親人兩行淚 ''';
  const line2 = """ 道路千萬條,安全第一條, 行車不規範,親人兩行淚 """;
複製代碼

轉義符號

聲明raw字符串(前綴爲r),在字符串前加字符r,或者在\前面再加一個\,能夠避免\的轉義做用,在正則表達式裏特別有用

// 轉義字符
  print(r'轉義字符, \n');
  print('轉義字符, \\n');
  print('轉義字符, \n');
複製代碼

屬性介紹

const string0 = 'https://www.titanjun.top/';
  
  // 可根據索引獲取字符串的每個字符
  print(string0[1]);

  // 字符串是不是空的
  print(string0.isEmpty);
  print(''.isEmpty); // true
  // 字符串是否不是空的
  print(string0.isNotEmpty);
  print(''.isNotEmpty);  // false

  // 返回字符串Unicode代碼的可迭代對象
  print(string0.runes);
  // 返回字符串的UTF-16代碼單元列表
  print(string0.codeUnits);
  // 返回根據代碼單元生成的哈希碼
  print(string0.hashCode);
  // 字符串的長度
  print(string0.length); 
  // 返回對象運行時的類型
  print(string0.runtimeType);  // String
複製代碼

方法介紹

const string0 = 'https://www.titanjun.top/';
  
  // 字符串比較
  print('titan'.compareTo('jun'));
  
  // 大小寫轉換
  print(string0.toUpperCase());
  print(string0.toLowerCase());

  // 截取字符串(開頭索引和結尾索引)
  print(string0.substring(0, 5)); // https
  // 只有開頭索引, 默認截取到最後
  print(string0.substring(12));  // titanjun.top/

  // 拆分字符串
  print(string0.split('.'));  // [https://www, titanjun, top/]
  print(string0.split(new RegExp(r"t")));  // [h, , ps://www., i, anjun., op/]

  // 去掉字符串裏面的tab空格和換行符
  const string1 = '\t\ttitanjun top\n';
  print(string1.trim());
  // 去掉字符串開頭的tab空格和換行符
  print(string1.trimLeft());
  // 去掉字符串結尾的tab空格和換行符
  print(string1.trimRight());
複製代碼

endsWith

判斷字符串是否以某字符(字符串)結尾, 參數不接受正則表達式

const str1 = 'titanjun.top';
  print(str1.endsWith('p'));  //true
  print(str1.endsWith('/'));  //false
  print(str1.endsWith('top'));  //true
複製代碼

startsWith

bool startsWith(Pattern pattern, [int index = 0]);
複製代碼

判斷字符串是否以某字符(字符串)開頭, 參數接受正則表達式

const str1 = 'titanjun.top';
  print(str1.startsWith('h'));  //false
  print(str1.startsWith('tit')); //true
  print(str1.startsWith('it', 1)); //true
  print(str1.startsWith(new RegExp(r'[A-Z][a-z]'), 1)); //false
複製代碼

indexOf

int indexOf(Pattern pattern, [int start]);
複製代碼
  • 根據指定的字符(字符串)獲取其在原字符串中第一次出現的索引值, 順序是從左到右
  • 能夠從指定的索引初開始, 默認從0開始
  • 若是原字符串中沒有須要查找的字符(字符串), 則返回值爲: -1
const str2 = 'https://www.titanjun.top/';
  print(str2.indexOf('titan')); // 12
  print(str2.indexOf('t', 5));  // 12
  print(str2.indexOf(new RegExp(r'[a-z]'))); //0
  // 若是沒有改字符, 則會輸出-1
  print(str2.indexOf('ppp'));  // -1
複製代碼

lastIndexOf

int lastIndexOf(Pattern pattern, [int start]);
複製代碼

效果和indexOf同樣, 不一樣點則是: indexOf的順序是從左到右, lastIndexOf是從右到左

const str2 = 'https://www.titanjun.top/';
  print(str2.lastIndexOf('t', 20));  //14
  print(str2.indexOf(new RegExp(r'[a-z]'))); //0
  // 若是沒有改字符, 則會輸出-1
  print(str2.indexOf('ppp'));  // -1
複製代碼

補佔位符

String padLeft(int width, [String padding = ' ']);
String padRight(int width, [String padding = ' ']);
複製代碼
  • 在字符串先後補佔位符
  • 參數一: 想要獲得的字符串的位數
  • 參數二: 位數不足時, 補充的字符
const str3 = '12';
  print(str3.padLeft(2, '0')); //12
  print(str3.padRight(3, '0')); // 120
複製代碼

contains

bool contains(Pattern other, [int startIndex = 0]);
複製代碼
  • 判斷字符串中是否包含某字符
  • 判斷指定索引處的字符是不是某字符
bool contains(Pattern other, [int startIndex = 0]);

const str = 'Dart strings';
print(str.contains('D'));
print(str.contains(new RegExp(r'[A-Z]')));
print(str.contains('D', 0));
print(str.contains(new RegExp(r'[A-Z]'), 0));
複製代碼

替換字符

// 只能替換一次, 參數三爲開始的索引值, 默認0
String replaceFirst(Pattern from, String to, [int startIndex = 0]);

// 替換全部符合條件的字符(字符串)
String replaceAll(Pattern from, String replace);

// 替換某一區間的字符
String replaceRange(int start, int end, String replacement);

// 示例以下:
// 替換字符串
  const str4 = 'titanjun12--0123';
  print(str4.replaceFirst('t', 'T'));  // Titanjun12--0123
  print(str4.replaceFirst('12', '21', 10));   //titanjun12--0213

  // 所有替換
  print(str4.replaceAll('12', '21'));  //titanjun21--0213
  print(str4.replaceAll('t', 'T'));  //TiTanjun12--0123

  // 區間替換
  print(str4.replaceRange(0, 5, 'top'));  //topjun12--0123
複製代碼

List

DartList對象就是其餘語言中的數組

建立數組

// 建立一個指定長度的List, 不能添加/刪除元素
List([int length]);

//經過指定長度建立一個固定長度的List,並使用fill初始化每一個位置的值, 不能添加/刪除元素
List.filled(int length, E fill, {bool growable: false});

//建立一個包含全部elements的List, 
//當growable爲true(默認)時,構造函數返回一個可增加的List。 不然,它返回一個固定長度的List
List.from(Iterable elements, {bool growable: true})

//生成一個包含全部值的List
//除非growable爲true(默認),不然建立的List是固定長度的
List.generate(int length, E generator(int index), {bool growable: true})

//建立一個包含全部elements的,不能改變它的長度或元素
List.unmodifiable(Iterable elements)
複製代碼

List

  • 若是設置了參數length(length不能爲負數或null),那麼建立的List是固定長度的
  • 元素可修改, 元素個數不可修改, 不能刪除和增長元素
var l1 = new List(3);  //[null, null, null]
print(l1.length);  //3

// 下面這種寫法會報錯
l1.length = 1;
複製代碼

若是未設置參數length,那麼List的長度是0,而且是可增加的

// 這兩種方式同樣
var l10 = new List();
var l11 = [];

// 都是可行的
l10.length = 3;
l10.add(1);
複製代碼

當使用指定長度建立一個可增加的List時,僅僅在剛建立後分配長度

List growableList = new List()..length = 500;
複製代碼

filled

  • 經過指定長度建立一個固定長度的List,並初始化每一個位置的值
  • 全部的元素都是相同的fill值。 若是指定的值是一個可變對象,那麼List中全部的元素都是相同的對象,而且是可修改的
var l2 = new List.filled(3, 'l');  //[l, l, l]
  var l3 = new List.filled(2, []);   // [[], []]
  l3[0].add(12);   
  print(l3);      // [[12], [12]]
複製代碼

from

  • 建立一個包含全部elementsList
  • elementsIterator規定了元素的順序。
  • growabletrue(默認)時,構造函數返回一個可增加的List。 不然,它返回一個固定長度的List
var l5 = new List.from([1, 2, 3, 4]);
l5.add(5);
print(l5);   // [1, 2, 3, 4, 5]

// 下面的add方法會報錯
var l5 = new List.from([1, 2, 3, 4], growable: false);
l5.add(5);
複製代碼

generate

  • 生成一個包含全部值的List, 根據索引值建立元素
  • growablefalse時,建立的List是固定長度的
var l4 = new List.generate(3, (int i) => i * i);
l4.add(14);
print(l4);
// [0, 1, 4, 14]
複製代碼

unmodifiable

  • 建立一個包含全部elements的,不可修改的List
  • 不可修改的List不能改變它的長度或元素
  • 若是元素自己是不可改變的,那麼由此產生的List也是不可改變的
var l6 = new List.unmodifiable([1, 2, 3, 4]);
複製代碼

List屬性

var arr1 = [1, 2, 3, 4];
  // 數組的第一個和最後一個元素
  print(arr1.first);  // 1
  print(arr1.last);   // 4

  // 判斷數組是否爲空
  print(arr1.isNotEmpty);  // true
  print(arr1.isEmpty);     // false

  // 數組長度, 元素個數
  print(arr1.length);  // 4

  // 倒序返回List
  print(arr1.reversed);  // [4, 3, 2, 1]

  // 返回Iterator,被容許迭代Iterable的全部元素
  print(arr1.iterator);

  // 對象的運行時類型
  print(arr1.runtimeType);   // List<int>

  // 獲取對象的哈希值
  print(arr1.hashCode);
  
  // 根據索引獲取元素
  print(arr1[2]);

  // 根據索引修改元素
  arr1[1] = 11;
  print(arr1);
複製代碼

List方法

增長

// 添加元素
  arr1.add(5);

  // 添加一個數組
  arr1.addAll([10, 12]);
複製代碼

查找

var arr2 = ['one', 'two', 'three', 'one', 'four'];

  // 是否包含某元素
  print(arr2.contains('one'));  // true
  // 判斷數組是否有知足條件的元素
  print(arr2.any((item) => item.length > 4));  // true
  // 判斷數組是否全部元素都知足條件
  print(arr2.every((item) => item.length > 4));  // false
  
  // 轉化爲Map類型, 索引做爲Key值,對應的元素做爲Value
  print(arr2.asMap());  // {0: one, 1: two, 2: three, 3: one, 4: four}
  
  //隨機打亂List中的元素
  arr2.shuffle();

  // 經過索引獲取元素, 等價於arr2[3]
  print(arr2.elementAt(3));

  // 獲取元素對應的索引值, 默認從索引0開始
  print(arr2.indexOf('one'));  // 0
  // 從第2個索引開始查找
  print(arr2.indexOf('one', 2));  // 3
  // 若是找不到, 返回-1
  print(arr2.indexOf('five'));  // -1

  // 獲取元素對應的索引值, 從後往前找
  print(arr2.lastIndexOf('one'));
  print(arr2.lastIndexOf('one', 3));
  print(arr2.lastIndexOf('five'));
  
  // 返回知足條件的第一個元素
  print(arr3.firstWhere((item) => item == 'one'));
  
  // 查找符合條件的元素, 若是有且僅有一個符合條件的元素, 則返回該元素
  // 若是沒有匹配到元素,或匹配到多個元素, 則會拋出異常
  print(arr2.singleWhere((item) => item.length == 5));  //three
  
  // 返回除了最初的count個元素外的全部元素
  arr2 = ['one', 'two', 'three', 'four'];
  print(arr2.skip(2)); // (three, four)

  // 返回全部不符合該條件的元素
  print(arr2.skipWhile((item) => item.length == 3));  //(three, four)

  // 返回一個新的List,包含從start(包括)到end(不包括)的對象, 原數組不變
  print(arr2.sublist(1, 3));
  // 不指定end, 默認到數組結尾
  print(arr2.sublist(2));
  
  // 獲取某一區間的元素, 返回一個數組
  print(arr2.getRange(1, 3));    // ['two', 'three']
  
  // 數組拼接成字符串
  print(arr2.join());  //onetwothreefour
  print(arr2.join('-'));  //one-two-three-four

  // 返回數組最初的count個元素
  print(arr2.take(2));
  // 返回數組符合條件的元素, 直到條件值爲false中止過濾
  arr2 = ['one', 'two', 'three', 'four', 'ten'];
  print(arr2.takeWhile((item) => item.length == 3));  //(one, two)
複製代碼

刪除

var arr2 = ['one', 'two', 'three', 'one', 'four'];
  
  // 刪除指定的元素
  // 若是有該元素, 返回true
  print(arr2.remove('two'));  // true
  print(arr2);   // [one, three, one, four]
  // 若是沒有該元素, 返回false
  print(arr2.remove('five'));  // false

  // 根據索引刪除, 返回被刪除的元素值
  print(arr2.removeAt(1));  // three
  print(arr2);   // [one, one, four]

  // 刪除最後一個元素, 返回該元素值
  print(arr2.removeLast());  // four
  print(arr2); // [one, one]

  // 刪除一個區間的元素, 含左不含右[start, end)
  arr2.addAll(['six', 'seven', 'eight']);
  arr2.removeRange(1, 3);
  print(arr2);  // [one, seven, eight]

  // 刪除全部符合條件的元素
  arr2.removeWhere((item) => item.length == 3);
  print(arr2);  // [seven, eight]
  
  //刪除List中全部不知足條件的元素
  arr2.retainWhere((item) => item.length > 3);
  print(arr2);
  
  // 刪除全部的元素
  arr1.clear();
  print(arr1);  // []
複製代碼

插入

var arr3 = [1, 3, 4];
  // 在某處插入元素
  arr3.insert(1, 10);
  print(arr3); //[1, 10, 3, 4]

  // 插入一個數組
  arr3.insertAll(2, [12, 32]);
  print(arr3);
複製代碼

重要方法

//過濾
Iterable<E> where(bool test(E element)) => new WhereIterable<E>(this, test);

// 映射
Iterable<T> map<T>(T f(E e)) => new MappedIterable<E, T>(this, f);

// 排序
void sort([int compare(E a, E b)]);

// 迭代計算, initialValue: 初始值, combine: 計算函數
T fold<T>(T initialValue, T combine(T previousValue, E element))

// 迭代計算, 初始值即爲第一個元素的值, combine: 計算函數
E reduce(E combine(E value, E element))

// 對集合的每一個元素,按迭代順序執行函數操做
void forEach(void f(E element))

// 將Iterable的每一個元素擴展爲0個或多個元素
Iterable expand(Iterable f(E element))
複製代碼

下面看一下每個函數的具體使用和介紹

var arr2 = ['one', 'two', 'three', 'four'];
  
  // 過濾操做, 返回全部符合條件的元素
  print(arr2.where((item) => item.length == 3));  //(one, two, ten)
  
  // 映射一個新的數組, 參數是一個函數
  var array = arr2.map((item) {
    return item + '-';
  });
  print(array.toList());  // [one-, ten-, two-, four-, three-]
  
  // 排序, 默認從小到大
  arr2.sort();
  print(arr2);  //[four, one, ten, three, two]
  // 設置條件進行排序
  arr2.sort((item1, item2) {
    // 若是兩個比較的結果爲0, 那麼排序後返回的結果可能不一樣
    return item1.length.compareTo(item2.length);
  });
  print(arr2);  //[one, ten, two, four, three]

  // 迭代計算, initialValue: 初始值, combine: 計算函數
  var arr4 = [1, 2, 3, 4];
  // 設置初始值
  var result1 = arr4.fold(10, (prev, value) => prev + value);  //20
  var result2 = arr4.fold(2, (prev, value) => prev * value);  //48
  // 初始值即爲第一個元素的值, 可迭代對象至少要有一個元素。 若是它只有一個元素,則元素直接返回
  var result3 = arr4.reduce((value, element) => value * element);  // 24

  // 對每個元素進行操做
  arr2.forEach((item) {
    print(item);
  });
  
  // expand, 以對每一個元素調用f函數後生成的元素,按迭代的順序,返回新的Iterable
  var pairs = [[1, 2], [3, 4]];
  var flattened = pairs.expand((pair) => pair).toList();
  print(flattened); // => [1, 2, 3, 4];

  var input = [1, 2, 3];
  var duplicated = input.expand((i) => [i, i]).toList();
  print(duplicated); // => [1, 1, 2, 2, 3, 3]
複製代碼

因爲篇幅太長了, 剩下的一些數據類型下篇文章在繼續研究記錄吧

參考文獻


歡迎您掃一掃下面的微信公衆號,訂閱個人博客!

微信公衆號
相關文章
相關標籤/搜索