Dart2学习笔记

官网教程,也是我的学习参照!
为了学习flutter,所以来学习Dart(本文所有的Dart均代指Dart2),奈何中文版是Dart1的教程,博客上偶有一篇Dart2的教程也是零零散散,没办法只能跟着官网教程学习!

基本Dart程序

先来一个基本的Dart程序:

//比较简单的英语就不翻译了
// Define a function.
printIntege(int aNumber) {
  print('The number is $aNumber.'); // Print to console.
}

//这里是主函数 This is where the app starts executing.
main() {
  var number = 42; // Declare and initialize a variable.
  printInteger(number); // Call a function.
}

从上面的程序,可以总结延伸以下知识点:

  • 单行注释 //this is single-line comment Dart也支持多行注释/*this is multi-line comment*/
  • Dart的数据类型numbers、strings、booleans、lists (also known as arrays)、maps、runes (for expressing Unicode characters in a string)、symbolsbuilt-in types
  • print()是一个ie输出函数
  • '...' (or "...") 字符串的形式
  • 通过$variableName (or ${expression}) 的形式,可以向字符串中插入变量
  • main() 主函数,程序从这里开始执行
  • var 用于声明不指定类型的变量

Dart语法规则

  • Dart中所有的变量包括数字、函数和null 都是对象,每一个 对象都是一个类的实例,他们都继承于Object
  • Dart是强类型语言,但是生明变量时也可以不指定类型,因为Dart可以自动推断,在上面的例子中,变量number就被自动推断为int类型
  • Dart支持泛型,如List<int>表示集合元素类型为整型、List<dynamic>表示元素类型为任何类型
  • Dart除了支持我们常见的静态函数(类直接调用)和普通函数(对象调用)外,同时也支持顶级函数如main() 和嵌套函数(函数里面的函数,也叫本地函数)
  • 与函数类似,Dart也支持顶级变量,同时支持静态变量和实例变量,实例变量也被叫做字段或属性
  • 和java不同,Dart没有public、protected、private权限修饰符,在Dart里面的以下划线_开头的标志符表示是私有的
  • Dart里面的标志符号由_、字母和数字组成,只能以_或者字母开头
  • 要注意区分表达式和语句的不同,如var a = 3 + 2; //整体是一个赋值语句,“=”右边部分即"3 + 2"是一个表达式
  • Dart工具会向你发出两种类型的提醒:警告和错误。警告代表你的代码可能有问题,但是不会阻止程序的运行;错误分为编译错误和运行错误,前者会阻止程序的运行,后者则会在程序运行使抛出异常!

关键字

这里写图片描述
上面带有字样1的是内置标志符号,这些不能作为ie变量名,带有2字样的是Dart2新增的用于支持异步的关键字,其他的都是保留字!

变量

变量的声明及其默认值

变量声明有以下几种方式:

var name = 'Bob'; //类型自动推断
dynamic name = 'Bob';//dynamic表示变量类型不是单一的
String name = 'Bob';//明确声明变量的类型
int lineCount;//所有的变量包括数字类型,如果没有初始化,其默认值都是null

Final and const
如果你的变量不会发生变化,可以使用final或const来声明。final声明的变量的值只能被设置一次。const是一个编译时便常量,本质上是一个隐式的final,实例常量可以被声明为final,但是不能为const!说人话就是final可以用变量来声明,const不能!

final name = 'Bob'; // Without a type annotation
// name = 'Alice';  // Uncommenting this causes an error
final String nickname = 'Bobby';

const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere

const关键字不仅可以声明常量字段,也可以用于创建恒定的值,如:

// Note: [] creates an empty list.
// const [] creates an empty, immutable list (EIL).
var foo = const []; // foo is currently an EIL.
final bar = const []; // bar will always be an EIL.
const baz = const []; // baz is a compile-time constant EIL.

// You can change the value of a non-final, non-const variable,
// even if it used to have a const value.
foo = [];

// You can't change the value of a final or const variable.
// bar = []; // Unhandled exception.
// baz = []; // Unhandled exception.
//foo的值可以改变,bar baz不能再变
const list = [1, 2, 3]; // error
const list = const [1, 2, 3]; // ok
const list = const [new DateTime.now(), 2, 3]; // error, because new DateTime.now() is not const
const list = const [const X(3), 2, 3]; // ok

final list = [1, 2, 3]; // ok
final list = const [1, 2, 3]; // ok
final list = const [new DateTime.now(), 2, 3]; // error, because new DateTime.now() is not const

数据类型

前面也有提到,Dart有七种内置的数据类型

  • numbers
  • strings
  • booleans
  • lists (also known as arrays)
  • maps
  • runes (for expressing Unicode characters in a string)
  • symbols

numbers
Dart有两种数字类型int和double,int的范围取决于平台,Dart VM是64位 ,如果是使用 JavaScript numbers编译为JavaScript,那么其范围ie是54为ie

double
64位浮点型数据

int和double都是num的子类型,num包含基本操作符如+ - / *,同时也有众多的方法如abs() ceil() floor()等,int里面还有位操作符如>>,更多详细内容参见dart:math.

//整型不带小数点
int x = 1;
int hex = 0xDEADBEEF;

//带小数点的要声明为double
double y = 1.1;
double exponents = 1.42e5;
//字符串和数字类型的转换
// String -> int
var one = int.parse('1');
// String -> double
var onePointOne = double.parse('1.1');
// int -> String
String oneAsString = 1.toString();
// double -> String
String piAsString = 3.14159.toStringAsFixed(2);
//整型的位运算
 var a = 3 << 1;//6 向左移动一位相当于3*2
 var b = 3 >> 1;//1 向右移一位
 var c = 3 | 1; //3  0011 | 0001 == 0011
 var d = 3 & 1;//1  0011 & 0001 == 0001

Strings

//字符串的写法有以下三种,当然也可以嵌套
var s1 = 'ssss1';
var s2 = "sssss2";
var s3 = '''  //三个 ' 或 " 来定义多行的String 类型
ssss
3333
''';

//字符串内嵌入变量 嵌入表达式 $variableName (or ${expression})
var s4 = "s4---$s1";//s4---ssss1 

//拼接字符串
var s5 = 'dd''ff'
   "ee";
//上面的方法等价于
var s6 = 'dd' + 'ff' + "ee"; 

//可以通过加前缀r的方式,创建一个"raw"(原始)的字符串
//说白了 就是让字符串内的任何表达式、语法实效,原样输出
var s7 = r"In a raw string, even \n isn't special.${3+3}";
//In a raw string, even \n isn't special.${3+3}

Booleans
Dart是强布尔类型检查,只有当值是true是才为真,其他都是false,声明时用bool

Lists 类型
在 Dart 语言中,具有一系列相同类型的数据被称为 List 对象。
Dart List 对象类似JavaScript 语言的 array 对象。

var list = [1, 2, 3];//分析器自动推断list为List<int>,所以里面不能加入其他类型的元素
print(list.length);//3
list[1] = 11;
print(list.toString());//[1, 11, 3]
var constantList = const [1, 2, 3];
// constantList[1] = 1; //因为前面的赋值使用了const 所以这句会报错. 
constantList= [5];//这样可以

Maps
map是一个包含key和value的对象,key不能重复

var gifts = {
  // Key:    Value
  'first': 'partridge',
  'second': 'turtledoves',
  'fifth': 'golden rings'
};

var nobleGases = {
  2: 'helium',
  10: 'neon',
  18: 'argon',
};

var gifts2 = new Map();
gifts['first'] = 'partridge';
gifts['second'] = 'turtledoves';
gifts['fifth'] = 'golden rings';

var nobleGases2 = new Map();
nobleGases[2] = 'helium';
nobleGases[10] = 'neon';
nobleGases[18] = 'argon';

//获取value
print(gifts2['first']);// partridge;
print(gifts2.length);// 3

Runes
Dart 中 使用runes 来获取UTF-32字符集的字符。String的 codeUnitAt and codeUnit属性可以获取UTF-16字符集的字符

var clapping = '\u{1f44f}';
print(clapping);
print(clapping.codeUnits);
print(clapping.runes.toList());

Runes input = new Runes(
  '\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d}');
print(new String.fromCharCodes(input));

Symbols
symbol字面量是编译时常量,在标识符前面加#。如果是动态确定,则使用Symbol构造函数,通过new来实例化.你可能永远也不用不到Symbol

 print(#s == new Symbol('s'));//true

函数

Dart是面向对象的语言,function也是一种对象,可以赋值给一个变量,可以作为其他函数的参数

//下面的函数省略bool也可以,但是不建议那样做
bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}
//如果函数只有一条语句或表达式,可以采用简略的形式
//bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
// => expr 也可以写成 { return expr; }的样式

可选参数
函数的参数有两种类型:必传、可省略,即调用函数时前者必须传,后者可以不传

/*
    bold 和 hidden是可选的参数  用{}指定可选参数的名称,调用时使用paramName: value的形式传参
*/
  void enableFlags(bool b1,{bool bold, bool hidden}) {
    print(bold);
    print(hidden);
    }
   enableFlags(true, hidden: false);//true null false   
/*
    device是可选的参数,用[]标识可选参数的位置
*/
String say(String from, String msg, [String device]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  return result;
}

say('Bob', 'Howdy');//Bob says Howdy
say('Bob', 'Howdy', 'smoke signal')//Bob says Howdy with a smoke signal

可以为可选参数设置默认值,如果不设置默认为null

/// Sets the [bold] and [hidden] flags ...
void enableFlags({bool bold = false, bool hidden = false}) {
  // ...
}

// bold will be true; hidden will be false.
enableFlags(bold: true);
String say(String from, String msg,
    [String device = 'carrier pigeon', String mood]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  if (mood != null) {
    result = '$result (in a $mood mood)';
  }
  return result;
}
say('Bob', 'Howdy');//Bob says Howdy with a carrier pigeon
  void doStuff({List<int> list = const [1, 2, 3],
                Map<String, String> gifts = const { 'first': 'paper'}}) {
    print('list:  $list');
    print('gifts: $gifts');
}
  doStuff();//list:  [1, 2, 3]     gifts: {first: paper}

主函数
每一个程序都要有一个主函数,它是app的入口,无返回值,有一个List<String>类型的可选参数。
下面是一个web app的主函数:

void main() {
  querySelector('#sample_text_id')//获取页面上的button对象
    ..text = 'Click me!'//设置文本
    ..onClick.listen(reverseText);//设置监听
}

注:..是一种级联操作符,它返回调用者本身,这样就可以连续调用同一个对象上的多个方法,实现链式操作!

下面是一个带参的主函数,需要命令行操作:

// Run the app like this: dart args.dart 1 test
//运行程序:dart args.dart 1 test
//args.dart是程序文件名 1 test是参数
void main(List<String> arguments) {
  print(arguments.length);//2
  print(int.parse(arguments[0]));//1
  print(arguments[1]);//test
}

函数对象

函数可以作为一个参数

void printElement(int element) {
  print(element);
}

var list = [1, 2, 3];

// Pass printElement as a parameter.
list.forEach(printElement);// 1  2  3

函数可以赋值给一个变量

var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
print(loudify('hello'));//!!! HELLO !!!

上面用到了匿名函数,下面的模块将会详细介绍。

匿名函数
大多数函数都有名字,如main(),没有名字的函数被称为匿名函数,有时也叫做闭包或lambda

var list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
  print('${list.indexOf(item)}: $item');
});
//上面的函数可以改写为箭头函数
list.forEach(
    (item) => print('${list.indexOf(item)}: $item'));
//0: apples    1: bananas     2: oranges

作用域
内层的函数可以访问外层函数的变量,反之则不行

bool topLevel = true;

void main() {
  var insideMain = true;

  void myFunction() {
    var insideFunction = true;

    void nestedFunction() {
      var insideNestedFunction = true;

      assert(topLevel);
      assert(insideMain);
      assert(insideFunction);
      assert(insideNestedFunction);
    }
  }
}

闭包

/// Returns a function that adds [addBy] to the
/// function's argument.
Function makeAdder(num addBy) {
  return (num i) => addBy + i;
}

void main() {
  // Create a function that adds 2.
  var add2 = makeAdder(2);

  // Create a function that adds 4.
  var add4 = makeAdder(4);

  assert(add2(3) == 5);
  assert(add4(3) == 7);
}

后续有时间会跟上的

猜你喜欢

转载自blog.csdn.net/chaoyangsun/article/details/80529573