Dart语法快速入门

Dart的官网地址:https://www.dartlang.org/guides/language/language-tour#libraries-and-visibility

在Dart中有一个基本的概念需要先了解:

  1. 在 dart 中,所有的东西都是对象,无论是变量,数字或函数,所有的对象都是类的实例(包括null),所有的对象都从 Object 类继承
  2. 尽管Dart是强类型的,但类型注释是可选的,因为Dart可以推断类型。在上面的代码中,number 推断为类型int。如果要明确说明不需要任何类型,请 使用特殊类型dynamic
  3. Dart支持泛型类型,如List<int>(整数列表)或List<dynamic>(任何类型的对象列表)。
  4. Dart支持顶级函数(例如main()),以及绑定到类或对象的函数(分别是静态方法(static方法)实例方法(new对象后))。您还可以在函数内创建函数(嵌套函数本地函数)。
  5. 类似地,Dart支持顶级变量,以及绑定到类或对象的变量(静态和实例变量)。实例变量有时称为字段或属性。(全局变量和局部变量类似的概念)
  6. 不具备关键字publicprotectedprivate。如果标识符以下划线(_)开头,则它对其库是私有的

dynamic说明:

dynamic可以在两种情况下使用,

一种是:Dart的类型系统不够复杂,无法表示允许的类型集,或者值来自互操作或静态类型系统范围之外

一种是:希望运行时动态确认数据类型

void main(){
  // a 的数据类型可以随意改变,这种类型就是 dynamic
  var a ;
  a = 10;
  a = "dart";

  // 这里我们使用 dynamic 声明
  dynamic d = 10;
  d = '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);
    }
  }
}

在线运行dart:

https://dartpad.dartlang.org/

变量定义的关键字:

  • var:变量
  • dynamic:不指定类型
  • final:声明一个只能赋值一次的变量
  • const:常量,如果在类的级别进行生命,即作为整个类的变量的时候,需要使用static来修饰

支持的数据类型:

  • numbers
  • strings
  • booleans
  • lists (also known as arrays)
  • maps
  • runes (用于表示字符串中的Unicode字符)
  • symbols

numbers

var x = 1;
var y = 1.1;
int z = 1;

strings


String str = "sss";
String str2 = 'sssd';
var s = "1234";
assert('Dart has $s, which is very handy.' ==
    'Dart has string interpolation, ' +
        'which is very handy.');
//这里的$s表示使用上面的s的值
//assert表示判断括号内的结果是否为true,否则抛出一个错误

booleans

bool result = false;

lists

var list = [1, 2, 3];

maps

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

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

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

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

//这里Map()的新建,从Dart2开始,new为可选字段

runes


在Dart中,runes是字符串的UTF-32代码
Unicode为世界上所有系统中使用的字母,使用数字和符号定义唯一的数值。
由于Dart字符串是一系列UTF-16代码单元,因此在字符串中表示32位Unicode值需要特殊语法

表达Unicode代码点的常用方法是 \uXXXX,其中XXXX是4位十六进制值。例如,(♥)是\u2665。要指定多于或少于4个十六进制数字,请将值放在大括号中

例如,笑表情符号(?)是\u{1f600}

例子:
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));
}

结果:
?
[55357, 56399]
[128079]
♥  ?  ?  ?  ?  ?

symbols

老实说这块我不是很理解,写了个demo,感觉就像官网说的,以后可能永远都用不到

class MyApp extends StatelessWidget {


  @override
  Widget build(BuildContext context) {
    String str = "sss";
    String str2 = 'sssd';

    assert(new Symbol("sss") == #sss);
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
//        appBar: new AppBar(
//          title: new Text('Welcome to Flutter'),
//        ),
        body: new Center(
          child: new RandomWords(),
        ),
      ),
    );
  }
}

它正常运行下去了,仅此而已

方法Function:

常规方法

bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

Dart建议设置返回类型(void,其他),但如果省略类型,该函数仍然有效:

isNoble(atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

对于只包含一个表达式的函数,可以使用简写语法:

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

方法传参说明:

参数必传:
bool isNoble(int atomicNumber){...}

参数选传:
void enableFlags({bool bold, bool hidden}) {...}

enableFlags(bold:false)    //这样也可以调用


必传选传混杂:
String say(String from, String msg, [String device])
from,msg必传,device选传

void enableFlags({bool bold,@reqiured bool hidden}) {...}
此时hidden必传


选传参数默认值:
void enableFlags({bool bold = false, bool hidden = false}) {...}

String say(String from, String msg,
    [String device = 'carrier pigeon', String mood]){...}

void doStuff(
    {List<int> list = const [1, 2, 3],
    Map<String, String> gifts = const {
      'first': 'paper',
      'second': 'cotton',
      'third': 'leather'
    }}){...}



传入方法:
void printElement(int element) {
  print(element);
}

var list = [1, 2, 3];

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


方法比较:
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
assert(loudify('hello') == '!!! HELLO !!!');

匿名函数:

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

结果:
0: apples
1: bananas
2: oranges

类型操作符:

OperatorMeaning
asTypecast (also used to specify library prefixes)
isTrue if the object has the specified type
is!False if the object has the specified type
if (emp is Person) {
  // Type check
  emp.firstName = 'Bob';
}


(emp as Person).firstName = 'Bob';

值得备注的操作符:

// 赋值
a = value;
// 如果b为null则赋值,否则保持原样
b ??= value;

条件判断语句:

我这里就只列需要关注的东西了

for (int i = 0; i < candidates.length; i++) {
  var candidate = candidates[i];
  if (candidate.yearsExperience < 5) {
    continue;
  }
  candidate.interview();
}

这一段可以简写成:

candidates
    .where((c) => c.yearsExperience >= 5)
    .forEach((c) => c.interview());

switch与java有些不同

//不局限于int类型的值
var command = 'OPEN';
switch (command) {
  case 'CLOSED':
    executeClosed();
    break;
  case 'PENDING':
    executePending();
    break;
  case 'APPROVED':
    executeApproved();
    break;
  case 'DENIED':
    executeDenied();
    break;
  case 'OPEN':
    executeOpen();
    break;
  default:
    executeUnknown();
}

assert(断言)

结果为true则继续执行,为false则包错

// Make sure the variable has a non-null value.
assert(text != null);

// Make sure the value is less than 100.
assert(number < 100);

// Make sure this is an https URL.
assert(urlString.startsWith('https'));

错误处理:

Throw抛出异常

throw FormatException('Expected at least 1 section');

throw 'Out of llamas!';

Catch捕获异常

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  buyMoreLlamas();
}

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

Class类说明:

//正常的类创建,类的属性默认有getter和setter方法(非final属性),
class Point {
  num x;
  num y;

  //构造器语法糖
  Point(this.x, this.y);

  //新概念:命名构造器,在这个类会被继承,又本身需要构造器时,只能使用这种
  Point.fromJson(Map json) {
    x = json['x'];
    y = json['y'];
  }
}



//如果是用继承,则不能用常规构造器,只能使用命名构造器
class Person {
  String firstName;
    
  Person.fromJson(Map data) {
    print('in Person');
  }
}

class Employee extends Person {
  // 命名构造器使用父类的,就使用符号:
  Employee.fromJson(Map data) : super.fromJson(data) {
    print('in Employee');
  }
}

main() {
//命名构造器的使用方式
  var emp = new Employee.fromJson({});



简写方式:
class Employee extends Person {
  // ...
  Employee() : super.fromJson(findDefaultData());
}

Overridable operators(可覆写的操作符)

class Vector {
  final int x;
  final int y;
  const Vector(this.x, this.y);

  /// Overrides + (a + b).   可以将两个对象直接相加后产生新对象
  Vector operator +(Vector v) {
    return new Vector(x + v.x, y + v.y);
  }

  /// Overrides - (a - b).   可以将两个对象直接相减后产生新对象
  Vector operator -(Vector v) {
    return new Vector(x - v.x, y - v.y);
  }
}

main() {
  final v = new Vector(2, 3);
  final w = new Vector(2, 2);

  // v == (2, 3)
  assert(v.x == 2 && v.y == 3);

  // v + w == (4, 5)
  assert((v + w).x == 4 && (v + w).y == 5);

  // v - w == (0, 1)
  assert((v - w).x == 0 && (v - w).y == 1);
}

interfaces(隐式接口)

这里的interface接口和java不同在于,不需要定义interface,任何class都可以被implements

这里的interface接口和java不同在于,不需要定义interface,任何class都可以被implements

// A person. The implicit interface contains greet().
class Person {
  // In the interface, but visible only in this library.
  final _name;

  // Not in the interface, since this is a constructor.
  Person(this._name);

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

// An implementation of the Person interface.
class Imposter implements Person {
  // We have to define this, but we don't use it.
  final _name = "";

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

greetBob(Person person) => person.greet('bob');

main() {
  print(greetBob(new Person('kathy')));
  print(greetBob(new Imposter()));
}

Adding features to a class: mixins(为类添加新的功能)---类似于多继承

这是一个很值得注意的特性,这个特性很容易实现类似于多继承的实现

abstract class Musical {
  bool canPlayPiano = false;
  bool canCompose = false;
  bool canConduct = false;



  void entertainMe() {
    if (canPlayPiano) {
      print('Playing piano');
    } else if (canConduct) {
      print('Waving hands');
    } else {
      print('Humming to self');
    }
  }
}

class Person{
  final name = "name";
}

class Musician extends Person with Musical {
  // ...

  void doSome(){
    entertainMe();
    print(name);
  }

}


void main(){
    var mu = Musician();
    mu.canPlayPiano = true;
    mu.doSome();
}

泛型的使用:

与java中完全一致

Library库的说明:

库分两种类型

import 'dart:io';//对于内置的库,URI 使用特殊的 dart: scheme
import 'package:mylib/mylib.dart';//对于其他的库,你可以 package: scheme
import 'pk/met.dart';//对于其他的库,也可以直接使用路径

导入一部分库

// 只导入foo.
import 'package:lib1/lib1.dart' show foo;

// 除了foo都导入.
import 'package:lib2/lib2.dart' hide foo;

延迟加载入库

import 'package:deferred/hello.dart' deferred as hello;

greet() async {
  await hello.loadLibrary();// 使用 await 关键字暂停代码执行一直到库加载完成
  hello.printGreeting();
}

Asynchrony support(异步支持)

最常见的特性是 async 方法和 await 表达式。

async可以单独使用:

在一个方法上添加 async 关键字,则这个方法返回值为 Future。 例如,下面是一个返回字符串 的同步方法:


Future<String> lookUpVersion() async => '1.0.0';

如果使用 async 关键字,则该方法 返回一个 Future,并且 认为该函数是一个耗时的操作。

Future<String> lookUpVersion() async => '1.0.0';

例子:

//使用async之后方法的返回值为Future
getAppName() async{
  return "1111";
}

void main(){
    Future future = getAppName();
    future.then((onValue){//在then中获取实际返回的值
        return getAppName();//这里再返回一个Future
    }).then((onValue){//上面返回的还是Future,则再一次then来获取另一个Future中的值
        print(onValue);
    });
}

await必须和async一起使用:

//看起来就像同步代码一样
runUsingAsyncAwait() async {
  //...
  var entrypoint = await findEntrypoint();
  var exitCode = await runExecutable(entrypoint, args);
  await flushThenExit(exitCode);
}

//异步的错误捕捉
attached() async {
  super.attached();
  try {
    await appObject.start();
  } catch (e) {
    //...handle the error...
  }
}


异步的一些常用用法示例:

//串联异步请求
Future result = costlyQuery();

return result.then((value) => expensiveWork())
             .then((value) => lengthyComputation())
             .then((value) => print('done!'))
             .catchError((exception) => print('DOH!'));


//异步请求合并
Future deleteDone = deleteLotsOfFiles();
Future copyDone = copyLotsOfFiles();
Future checksumDone = checksumLotsOfOtherFiles();

Future.wait([deleteDone, copyDone, checksumDone])
    .then((List values) {
      print('Done with all the long steps');
    });

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值