dart语言学习笔记-2

默认值

如果变量未被初始化,变量的值为null

int lineCount;
assert(lineCount == null);

注:assert()的调用在生产阶段会被忽略

赋值

??=给空对象赋值

// Assign value to a
a = value;
// Assign value to b if b is null; otherwise, b stays the same
b ??= value;

final & const

final变量只能设值一次且需要在第一次使用时设值,const变量为编译期常量(隐式final)

注:实例变量可以为final,但不能为const。final的实例变量必须在构造器之前初始化,如变量声明、构造参数,或者构造器的初始化列表

final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';

const变量的值为数字、字符串,或他们的计算结果

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

const值

var foo = const [];
final bar = const [];
const baz = []; // Equivalent to `const []`

你可以修改非final,非const的变量,即使他的值为const

foo = [1, 2, 3]; // Was const []

内建数据类型

numbers

只包含int和double类型,且int不大于64bits,double为64bit

int会自动转为double

double z = 1; // Equivalent to double z = 1.0.

strings

Dart的string是一串UTF-16编码的字符,可以用单引号或双引号来创建

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.";

如果变量为表达式,可通过${expression}在创建字符串时来引用,如果是变量可以省略{},对象的话会默认调用toString()方法

var s = 'string interpolation';

assert('Dart has $s, which is very handy.' ==
    'Dart has string interpolation, ' +
        'which is very handy.');
assert('That deserves all caps. ' +
        '${s.toUpperCase()} is very handy!' ==
    'That deserves all caps. ' +
        'STRING INTERPOLATION is very handy!');

字符串可以通过相邻或者+来拼接

var s1 = 'String '
    'concatenation'
    " works even over line breaks.";
assert(s1 ==
    'String concatenation works even over '
    'line breaks.');

var s2 = 'The + operator ' + 'works, as well.';
assert(s2 == 'The + operator works, as well.');

如果要创建的是多行的字符串(包含换行),用三个引号包裹即可

var s1 = '''
You can create
multi-line strings like this one.
''';

var s2 = """This is also a
multi-line string.""";

如果要创建原始的非转义字符串,需要用r开头(和python相同)

var s = r'In a raw string, not even \n gets special treatment.';

booleans(true/false)

Dart为类型安全,所以不能像javascript那样使用if (nonbooleanValue)assert (nonbooleanValue)

lists

List代表有序集合,在Dart中的数组即为List对象

//Dart推断list代表List<int>,如果添加非int型对象会发出异常警告
var list = [1, 2, 3];

sets

Set代表无序集合

//Dart推断set代表Set<String>,只能添加string对象
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};

创建一个空的set,需要指明类型,如

var names = <String>{};
// Set<String> names = {}; // This works, too.
// var names = {}; // Creates a map of Map<dynamic, dynamic>, not a set.

注:小心创建了一个map对象
要创建一个编译期的常量,需要添加const前导

final constantSet =
    const {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
// constantSet.add('helium'); // Uncommenting this causes an error.

maps

两种初始化方式

//方式1
var gifts = {
  // Key:    Value
  'first': 'partridge',
  'second': 'turtledoves',
  'fifth': 'golden rings'
};
//方式2
var nobleGases = Map();
nobleGases[2] = 'helium';
nobleGases[10] = 'neon';
nobleGases[18] = 'argon';

构建编译期的常量时,需要添加前导const

final constantMap = const {
  2: 'helium',
  10: 'neon',
  18: 'argon',
};

// constantMap[2] = 'Helium'; // Uncommenting this causes an error.

runes

代表UTF-32编码的字符串


fromCharCodes
main() {
  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));
}

console output

👏
[55357, 56399]
[128079]
♥  😅  😎  👻  🖖  👍

当进行字符处理时,需要当心包含runes的情况,如

void main() {
  //一种情况
  var input = "Music \u{1f44d} for the win"; // Music 👍 for the win
  
  print(input.split('').reversed.join()); // niw eht rof �� cisuM
  
  print(new String.fromCharCodes(input.runes.toList().reversed)); // niw eht rof 👍 cisuM

  //另一种情况
  var input2 =  'Ame\u{301}lie'; // Amélie
  print(new String.fromCharCodes(input2.runes.toList().reversed)); // eiĺemA
}

symbols

Symbol对象代表声明的运算符或者标识符,你可能永远都不需要Symbol
通过#跟随标识符获取symbol

#radix
#bar

函数对象(Functions)

箭头表达式

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

注:=> expr;语法是{ return expr; }的简写,在=>之间只能是表达式,不能是其他如if

可选参数

Optional positional parameters

必选参数在前,可选参数在后

String say(String from, String msg, [String device]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  return result;
}

assert(say('Bob', 'Howdy') == 'Bob says Howdy');

Optional named parameters

通过{param1, param2, ...}的格式命名参数,用@required标记为必选参数,通过参数名称传值( 即paramName: value)方式调用

/// Sets the [bold] and [hidden] flags ...
void enableFlags({bool bold, @required bool hidden}) {...}
//使用时
enableFlags(bold: true, hidden: false);

参数默认值

定义时通过=赋值,且默认值必须是编译期常量,未赋值默认为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);

main函数

任何app都必须包括一个顶级的main(),作为app的入口函数,main()必须返回void,并有一个可选的List<String>参数。

void main() {
  querySelector('#sample_text_id')
    ..text = 'Click me!'
    ..onClick.listen(reverseText);
}

..语法是作为级联调用的

匿名函数

格式
([[Type] param1[, …]]) {
codeBlock;
};

var list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
  print('${list.indexOf(item)}: $item');
});

如果函数体只有一条语句,可以用箭头语法替换

list.forEach(
    (item) => print('${list.indexOf(item)}: $item'));

Lexical scope(词法范围)

Dart是一种词汇范围的语言,这意味着变量的范围是静态确定的,只需通过代码的布局。您可以“沿大括号向外”查看变量是否在范围内。

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);
    }
  }
}

Lexical closures(词法闭包)

closure(闭包)可以访问他所在的lexical scope(词法范围)的变量,即使被用到了在他原有的范围之外

/// 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);
}

特殊运算符

condition ? expr1 : expr2

如果condition为true,则调用expr1,否则调用expr2

expr1 ?? expr2

如果expr1非空,返回expr1的值,否则返回expr2的值

Cascade notation (..)

用前一个对象作为级联对象

final addressBook = (AddressBookBuilder()
      ..name = 'jenny'
      ..email = 'jenny@example.com'
      ..phone = (PhoneNumberBuilder()
            ..number = '415-555-0100'
            ..label = 'home')
          .build())
    .build();

?.

.运算符类似,如foo?.bar,如果foo非空,返回foo.bar,否则返回null

控制语句

switch and case

switch语句可以比较integer,string,或者用==比较编译期常量。待比较的对象必须是同一个类(不能为子类),并且这个类不能复写了==。枚举类适合switch语句。

注:某些情况下break不可缺少

var command = 'OPEN';
switch (command) {
  case 'OPEN':
    executeOpen();
    // ERROR: Missing break

  case 'CLOSED':
    executeClosed();
    break;
}

支持空的case,此时允许穿透

var command = 'CLOSED';
switch (command) {
  case 'CLOSED': // Empty case falls through.
  case 'NOW_CLOSED':
    // Runs for both CLOSED and NOW_CLOSED.
    executeNowClosed();
    break;
}

如果真的需要穿透,需要借助continue语句

var command = 'CLOSED';
switch (command) {
  case 'CLOSED':
    executeClosed();
    continue nowClosed;
  // Continues executing at the nowClosed label.

  nowClosed:
  case 'NOW_CLOSED':
    // Runs for both CLOSED and NOW_CLOSED.
    executeNowClosed();
    break;
}

try/throw/rethrow/catch/finally

  1. Dart可以throw任何对象,不仅限于exception
  2. 在判断throw时,on或者catch都可以(也可以同时使用),用on表示只关心抛出的类型,用catch表示关心抛出的具体对象
  3. catch时,堆栈为可选参数,即第一个参数为抛出的对象,第二个为堆栈(StackTrace)堆栈
  4. 通过rethrow,重新抛出该异常
    捕获单个throw
try {
  breedMoreLlamas();
} on OutOfLlamasException {
  buyMoreLlamas();
}

捕获多个throw

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // A specific exception
  buyMoreLlamas();
} on Exception catch (e) {
  // Anything else that is an exception
  print('Unknown exception: $e');
} catch (e) {
  // No specified type, handles all
  print('Something really unknown: $e');
}

带堆栈,并继续抛出异常

try {
  // ···
} on Exception catch (e) {
  print('Exception details:\n $e');
} catch (e, s) {
  print('Exception details:\n $e');
  print('Stack trace:\n $s');
  rethrow;// Allow callers to see the exception.
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • Built-in types(内置的类型) Dart 内置支持下面这些类型: numbers strings bo...
    Love零O阅读 581评论 0 4
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,731评论 2 9
  • 此文章是v1.0+时编写,年代久远,小心有毒,谨慎食用!!! 一些重要概念 所有的东西都是对象,所有的对象都是类的...
    soojade阅读 10,036评论 2 27
  • 七古逆行斋自题 顺行逆行两茫茫, 长天阔海任君翔。 梅花从来傲霜雪, 蝙蝠岂能沐阳光。 青松得地挺千尺, 落叶无依...
    逆行斋阅读 323评论 0 0
  • 今天我去给孩子们当护导。早晨比平常早起了十分钟,儿子知道我去学校做护导的事,也是迅速起床,积极配合我。做护导真...
    黛丽丝阅读 306评论 0 3