Dart語法學習


Dart語言特性:

  1. 在Dart中,一切都是對象,一切對象都是class的實例,哪怕是數字類型、方法甚至null都是對象,所有的對象都是繼承自Object
  2. 雖然Dart是強類型語言,但變量類型是可選的因為Dart可以自動推斷變量類型
  3. Dart支持范型,List<int>表示一個整型的數據列表,List<dynamic>則是一個對象的列表,其中可以裝任意對象
  4. Dart支持頂層方法(如main方法),也支持類方法或對象方法,同時你也可以在方法內部創建方法
  5. Dart支持頂層變量,也支持類變量或對象變量
  6. 跟Java不同的是,Dart沒有public protected private等關鍵字,如果某個變量以下划線(_)開頭,代表這個變量在庫中是私有的
  7. Dart中變量可以以字母或下划線開頭,后面跟着任意組合的字符或數字

變量與常量:

void main(){

  // 沒有明確類型,編譯的時候根據值明確類型
  var name0 = "字符串可以是雙引號";
  var name1 = '字符串也可以是單引號';
  //如果對象沒有明確的類型,可使用Object或dynamic關鍵字。
  Object name2 = '張三';//所有類都繼承於object
  dynamic name3 = '李四';//dynamic不是在編譯時候確定實際類型的, 而是在運行時。

  String name4 = 'Bob';// 顯示聲明類型

  // number
  var a = 0; // 自動推斷類型
  int b = 1;
  double c = 0.1;

  // string
  var s1 = 'hello';
  String s2 = "world";

  // boolean
  var real = true;
  bool isReal = false;

  // lists
  var arr = [1, 2, 3, 4, 5];
  List<String> arr2 = ['hello', 'world', "123", "456"];
  List<dynamic> arr3 = [1, true, 'haha', 1.0];
  arr3.forEach((item){
    print("item = $item");
  });

  // maps
  var map = new Map();
  map['key'] = 'value';

  var map2 = {"key1":"value1" , "key2":"value2"};
  //遍歷
  map2.forEach((key,value){
    print("key = ${key},value = ${value}");
  });
}

運行效果:

常量Final 和 Const的用法:

final和const的區別:

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

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

void main(){

  //被 final 或 const 修飾的變量無法再去修改其值。
  final String str = "string" + '拼接 string2';
  const String str2 = 'string';//被const修飾的變量是一個編譯時常量

  // flnal 或者 const 不能和 var 同時使用
  //final var str = '報錯';      這樣寫 報錯

  const Map map = {"key1":"value1"};
  const List list = [1,2];//const修飾的 List 對象地址不可變,集合長度也不可變(編譯時就確定了)

  final List list2 = new List();//final修飾的 List 對象地址不可變,集合長度可變
  list2.add("運行時常量,可添加");

  // 注意: [] 創建的是一個空的list集合
  // const []創建一個空的、不可變的列表。
  var varList = const []; // 對象地址可變,但是集合長度不可變
  final finalList = const []; // 兩者都不可變
  const constList = const []; // 兩者都不可變
  // varList.add("添加會報錯");

  // 可以更改非final,非const變量的地址
  varList = new List();

  // finalList = new List();//報錯 不可變

}

class a {

  //常量如果是類級別的,需要使用 static const
  static const speed = 100;

}

運算符:

Dart里面比較有代表性的以及有特點的一些運算符相關用法。

跟kotlin里一樣的?.

String a = null;
  //如果a 為 null,   a?.length = null
  print(a?.length);//輸出:null

  String b = "b";
  print(b?.length);//輸出:1

級聯符號..

 //相當於java的鏈式調用,  .. 返回對象本身
  String s = (new StringBuffer()
    ..write('test1 ') //write方法 返回的是 void
    ..write('test2 ')
    ..write('test3 ')
    ..write('test4 ')
    ..write('test5')
  ).toString();
  print(s); //輸出: test1 test2 test3 test4 test5

?? 三目運算符的一種形式

//普通三元運算符
  int a = 10;
  var values = a > 5 ? a : 0;
  print(values);//輸出: 10
  // ?? 操作符, expr1 ?? expr2 表示如果expr1非空,則返回其值; 否則返回expr2的值。
  print('${a ??= 3}');  //輸出: 10

~/ 除法,返回一個整數結果,其實就是取商。

var result1 = 15 / 7;// 除法
  print(result1); // 結果是:2.142857...
  
  var result2 = 15 ~/ 7;//取 商
  print(result2); // 結果是:2

  var result3 = 15 % 7; //取 余數
  print(result3); // 結果是:1

as、is與is!

as 判斷屬於某種類型
is 如果對象具有指定的類型,則為true
is! 如果對象具有指定的類型,則為false

String str = "str";
  bool a = true;

  //is 輸出是true 或者 false
  print(str is bool);  // false
  print(str is! bool);  // true

  //as 輸出是一個對象
  var asStr = str as String;
  print(asStr?.length);//輸出:3

控制流程語句 if else for循環 switch while

控制流程語句和Java語言差不多,下面只試下標記

for循環跳到指定標記處:

if語句中跳出代碼塊:

return就不測試了,跟java一樣

異常:

void main() {
  try {
    method1();
  }on FormatException catch (e) {
    //判斷 是否是 指定的FormatException異常
    print('main() 拿到異常 ${e.runtimeType} 異常信息:${e.message}');
  }catch (e,s) {//第一個參數是拋出的異常,第二個是堆棧跟蹤(StackTrace對象)。
    print('main() 拿到異常 ${e.runtimeType}}');
  }finally {
    print("finally 結束");
  }

  print("------------------------");

  try {
    method2();
  }catch (e,s) {//第一個參數是拋出的異常,第二個是堆棧跟蹤(StackTrace對象)。
    print('main() 拿到異常 ${e.runtimeType} 異常信息:${s}');
  }
}

void method1() {
  try {
    dynamic foo = true;
    print(foo++); // 運行時異常
  } catch (e) {
    print('異常了 ${e.runtimeType}');
    throw new FormatException("自己拋出異常");
  }
}

void method2() {
  try {
    dynamic foo = true;
    print(foo++); // 運行時異常
  } catch (e) {
    print('異常了 ${e.runtimeType}');
    rethrow; // 傳遞異常,允許調用者獲取exception.
  }
}

輸出日志:

方法:

方法的定義:

void main() {
  print(method1("method1"));
  print(method2("method2"));
  print(method3("method3"));

  //函數 也是 一個對象  使用 Function接收
  Function function = method1;//接收方法
  print(function("aaa"));//執行方法
}

String method1(String str) {
  return str;
}

// 返回類型  可省略
method2(String str) {
  return str;
}

//返回  null
method3(String str) {
  print(str);
}

輸出日志:

方法的傳參方式:

void main() {
  method1("第一種傳參方式");
  method2(str: "第二種傳參方式");
  method3(str: "第三種傳參方式");
}

void method1(String str) {
  print(str);
}

void method2({str: String}) {
  print(str);
}

void method3({String str}) {
  print(str);
}

默認參數,位置參數:

void main() {
  method1(1);
  method1(1,"傳參name","傳參name2");// [] 括起來的,直接傳, 按照參數位置定值

  method1_1(1);
  method1_1(1,name2: "傳參name2", name: "傳參name");// {} 括起來的,需要帶參數名稱,傳參位置隨意

  method2(2);

  method2(2);
  method2(2,"傳參name");

  method2_2(2);
  method2_2(2,name: "傳參name");

}

/**
 * []括起來的參數是函數的位置參數,代表該參數可傳可不傳,
 * 位置參數只能放在函數的參數列表的最后面
 */
String method1(int age, [String name,String name2]) {
  print("age = $age" + ",name = $name" + ",name2 = $name2");
}

/**
 * {} 括起來的參數  可傳 可不傳  還可以寫默認參數
 */
String method1_1(int age, {String name, String name2}){
  print("age = $age" + ",name = $name" + ",name2 = $name2");
}

//帶默認值
String method2(int age, [String name = "默認值"]) {
  print("age = $age" + ",name = $name");
}

String method2_2(int age, {String name = "默認值"}){
  print("age = $age" + ",name = $name");
}

匿名方法、方法作為參數:

/**
 *日志打印:
    第一種形式
    第二種形式
    第三種形式(匿名方法)
 */
main() {

  //第一種方法
  Function function = method;
  function("第一種形式");

  //簡寫  省略方法名了
  Function function2 = (String str){
    print(str);
  };
  function2("第二種形式");

  //匿名了  取消接收對象
  test((String param) {
    print(param);//接收方法
  });
}

// 方法的參數為  一個方法
test(Function aaa) {
  aaa("第三種形式(匿名方法)");//執行方法
}

method(String str){
  print(str);
}

類:

dart的中文官方文檔寫得很清楚

類的定義與構造方法

main() {
  var testChild = new TestChild();

  //通過 命名構造 來創建對象
  Test test = new Test.onlyX(2);

  test.y = 1;
  test.setX = 2;
  print(test.getX);
}

class Test{

  int x;//成員變量
  int y;

  /**
   * Dart提供了set和get關鍵字幫助我們更高效的訪問成員變量.
   *
   * 可以把它當做一個成員方法來看 */
  int get getX {
    return x;
  }

  set setX(int value) {
    x = x + value;
  }

  //Dart不像java可以使用多個同名不同參數構造。但是Dart提供了命名構造
  Test(this.x,this.y){
    print('x=${x}, y = ${y}');
  }

  // 命名構造
  Test.onlyX(int x) {
    this.x = x;
    y = 10;
    print('x=${x}, y = ${y}');
  }

}

/**
 * Dart中使用extends關鍵字做類的繼承,如果一個類只有命名的構造方法, * 在繼承時需要調用父類的命名構造方法 */
class TestChild extends Test{

  TestChild() : super(0, 0){
    print('這是 TestChild 類的空參構造');
  }

}

類的繼承

類的繼承跟java一樣

abstract class Doer {

  // 抽象方法,沒有方法體,需要子類去實現
  void doSomething();

  // 普通的方法
  void greet() {
    
  }
}

class EffectiveDoer extends Doer {

  // 需要實現父類的抽象方法
  @override
  void doSomething() {
    
  }
  
  //重寫父類的方法
  @override
  void greet() {
    super.greet();
  }

}

類的實現

/**
 * 日志:
      Hello, Bob. I am Person.
      Hi Bob. Do you know who I am?
 */
main() {
  print(greetBob(new Person('Person')));//調用Person 的 greet方法
  print(greetBob(new Impostor()));//調用Impostor 的 greet方法
}

String greetBob(Person person){
  return person.greet('Bob');
}

class Person {

  final _name;

  Person(this._name);

  String greet(String who) => 'Hello, $who. I am $_name.';
}

/**
 * Impostor實現Person接口 (隱式接口)
 * 接口是更純粹的抽象,使用接口時必須實現其定義的所有成員.(除了構造方法不能繼承) */
class Impostor implements Person {

  @override
  get _name => "Person的實現類";

  @override
  String greet(String who) => 'Hi $who. Do you know who I am?';

}

枚舉類

來之文檔中的截圖

mixin 類的混合

//作為 mixin的類  不能定義構造方法
class A {
  a() {
    print("A's a()");
  }
}

class B {
  b() {
    print("B's b()");
  }
}

// 使用with關鍵字,表示類C是由類A和類B混合而構成
class C with A,B,D {
  //C 擁有 A B D 的特性
}

// 不能通過new 來創建D對象
mixin D {
  void method() {
    print('mixin D 方法');
  }
}

main() {
  C c = new C();
  c.a(); // A's a()
  c.b(); // B's b()
  c.method();// mixin D 方法
}

導入庫import:

中文文檔說明

異步:

import 'package:http/http.dart' as http;
import 'package:http/http.dart';

void main(){

  getData().then((String data){
    print(data);
  });

}

/**
 * async 代表該方法是異步的
 * 異步函數,他的返回值將是一個Future */
Future<String> getData() async {
  //await 關鍵字聲明運算為延遲執行,然后return運算結果 await可以多次使用
  Response response = await http.get("http://www.baidu.com");
  print("請求成功:${response.body.substring(0,10)}");
  return response.body;
}

上面例子中需要引入第三方包 http, 導包方式

 

第三方庫搜索地址:https://pub.dev/

 

Dart對集合List的操作:

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM