Flutter中文社区Flutter圈子

Dart 基本语法及使用

2021-10-15  本文已影响0人  DaZenD

碎语,有android、iOS、前端、小程序、RN基础,所以,以下记录仅为个人理解记录,没必要的就忽略的

dart

一. dart 环境

需求:演练dart语法,直接运行.dart代码。。

$ dart xxx.dart

需要有dart环境支持

1 flutter中带的有sdk

安装flutter的时候,把dart的环境变量配置上即可

2 专门下载dart的sdk

https://dart.cn/get-dart

按文档安装dart sdk

1.1. vscode 演练dart

code runner 插件。

使用:右键-运行

二. 变量

跟ios像,优点是有类型推到,比如:var

dynamic 不建议使用

公私有性

dart中没有public,private,protected等,,

特殊 const

虽然js,oc里有,但是用法不一样,这个dart的还挺有意思

  final a = const Person();
  final b = const Person();
  print(identical(a, b)); // true

  final m = Person();
  final n = Person();
  print(identical(m, n)); // false

late 关键字

https://blog.csdn.net/weixin_44239910/article/details/118196797

late String temperature = _readThermometer();

dynamic

任意类型,是一个明确类型,比如

Map<String, dynamic> map

//这样是可以的
String str = map[''];
this.height = double.parse(map['height'].toString());

注意:使用as语法,你要提前知道类型,如果类型不匹配,就报错。

所以,所使用的方法的类型匹配的前提下,可以转换类型的。。

三. 数据类型

布尔

注意: Dart中不能判断非0即真, 或者非空即真
Dart的类型安全性意味着您不能使用if(非booleanvalue)或assert(非booleanvalue)之类的代码。

字符串

三引号,可以换行的字符串。打印结果也是换行的

var str = """
ab
bc
cd
""";

字符串拼接:对象可以省略{},表达式则不能省略{}

如:print('my name is ${name}, age is $age, height is ${xiaoming.height}');

集合类型

list,set,map 普通,没啥特别的

四. 函数

基本定义:

返回值 函数的名称(参数列表) {
  函数体
  return 返回值
}

4.1. 函数的可选参数

位置可选参数

注意形参:要有默认值

void method1(String name, [int age = 1, int? h]) {
  print('name is $name, age is $age, h is $h');
}

调用:

method1('name', 2);

结果:

name is name, age is 2, h is null

命名可选参数

void method2(String name, {int? age, String? add}) {
  print('name is $name, age is $age, h is $add');
}

调用:

method1('name', 33);

结果:

name is name, age is 33, h is null

注意:

4.2. 函数是一等公民

void method3(Function func) {

}

匿名函数

method3(() {
});

箭头函数

method3(() => print("xxx"));

只有一行代码的时候,可以使用箭头函数

注意:其实不太对,实践:

method3(() => {
  print("xxx"),
  print('object')
});

这样是可以的,只是要注意箭头函数体内不能有分号

函数形参

可以使用功能typedefine提出来函数定义

五. 运算符

??=

var name = null;
name ??= 'jjjj';

变量没有值,才执行??=

??

var s = null;
var ss = s ?? 'ssss';

?? 前没有值则用??后面的值

5.1. 级联运算符

final p2 = Person()
              ..name = "why"
              ..run()
              ..eat()
              ..swim();

特定语法,记住就行

六. 类和对象

默认继承 Object..跟 android 一样

6.1. 构造方法

6.1.1. 命名构造函数

class Person {
  String name = '';
  int age = 0;
  double height = 1.8;

  Person(this.name, this.age);
  Person.externalWithHieght(this.name, this.age, this.height);
  Person.fromMap(Map<String, dynamic> map) {
    this.name = map['name'];
    this.age = map['age'];
    this.height = map['height'];
  }
}

调用:

Person person = Person.externalWithHieght('name', 19, 1.9);
person = Person.fromMap({'name':'leixing', 'age':19, 'height':1.99});
print(person.toString());

6.1.2. 类的初始化列表

class Person1 {
  late final String name;
  final int age;

  //other field 其他参数可选列表,用逗号隔开
  Person1(this.name, {int? age, other field}) : this.age = age ?? 10, other field {

  }

  //这里也可以实现外部传值给final的age,,但是注意:requered表示外部初始Person1的时候必须传age,就失去了可选参数的意义
  Person1(this.name, {required this.age}) {

  }

  //也可以这样,,但是注意:局限性是命名可选参数里不能写表达式,比如三目运算符
  Person1(this.name, {this.age = 10}) {

  }

  Person1.withName(this.name) : age = 2 {

  }
}

针对age这种变量,如果在声明的时候指定初始值,那么外部就没办法再初始化的时候后指定值了。。

初始化列表: 可以使用这种技术,初始化列表就支持在运行的时候赋值final变量

解析:{int? age}是命名可选参数,后面的:xxx是初始化列表,这里是可以赋值的。。这样就解决了在方法体中对final变量赋值的动态需求

6.1.3. 重定向构造方法

class Person2 {
  String name;
  final int age;

  //重定向构造方法,用冒号,后面用this,表示前面已经初始化过了,后面可以使用this对象进行参数扩展
  //注意:重定向构造方法不能传可选参数。这是语法规定。可选参数只能供外部调用。内部调用只能调用最全的构造方法:_withNameAndAge
  //注意:形参要单纯,不能进行初始化,比如下面:只能 String name,而不能this.name。也就是说,不能先初始化了一部分,又去重定向。。这一点倒是没有java灵活
  //The redirecting constructor can't have a field initializer.
  //重定向构造方法,很像开发java的时候,那种入参较多,构造方法较多的情况。。
  Person2(String name): this._internal(name);
  Person2._internal(this.name, {int?age}): this.age = age ?? 1; 

  Person2._optionalAge(this.name, {this.age = 2});

  Person2.withName(String name): this._withNameAndAge(name, 1);
  Person2._withNameAndAge(this.name, this.age);

  @override
  String toString() {
    // TODO: implement toString
    return 'age is $age';
  }
}

6.1.4. 常量构造方法

main(List<String> args) {
  var p1 = const Person('why');
  var p2 = const Person('why');
  print(identical(p1, p2)); // true
}

class Person {
  final String name;

  const Person(this.name);
}

class Person3 {
  final String name;
  final int age;

  //注意:加了const,变量就必须是final的
  const Person3(String name): this._withAge(name, 1);
  const Person3._withAge(this.name, this.age);
}

const person3 = Person3._withAge('name', 222);
const person31 = Person3._withAge('name', 222);
print(identical(person3, person31));// true

常量构造函数,语法就是这么规定的,变量前加final,构造函数前加const

6.1.5. 工厂构造方法

main(List<String> args) {
  var p1 = Person('why');
  var p2 = Person('why');
  print(identical(p1, p2)); // true
}

class Person {
  String name;

  static final Map<String, Person> _cache = <String, Person>{};

  factory Person(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
    } else {
      final p = Person._internal(name);
      _cache[name] = p;
      return p;
    }
  }

  Person._internal(this.name);
}

6.1.6. setter和getter

class Person {
  String name = '';

  set setName(String name) {
    this.name = name;
  }

  set setName1(String name) => this.name = name;

  String get getName {
    return name;
  }
  //this写不写都可以,反正就是一个name变量,没有局部变量
  String get getName1 => this.name;
}

6.2. 类的继承

Person(String name, int age) : name=name, super(age);

6.3. 抽象类

抽象类如何实现实例化

6.4. 隐式接口

Dart中的接口比较特殊, 没有一个专门的关键字来声明接口.

默认情况下,定义的每个类都相当于默认也声明了一个接口,可以由其他的类来实现(因为Dart不支持多继承)

6.5. Mixin混入

在通过implements实现某个类时,类中所有的方法都必须被重新实现(无论这个类原来是否已经实现过该方法)。

但是某些情况下,一个类可能希望直接复用之前类的原有实现方案,怎么做呢?

6.6. 类成员和方法

跟普通语言一致

七. 枚举类型

可读性

类型安全

八. 泛型

同java

九. 库的使用

默认:一个dart文件就是一个库文件

使用系统的库

核心库不需要导入:'dart:core'

非核心库,用到的会自动导入:'dart:math'

封装库

dart_util.dart:

export 'math_util.dart'
export 'date_util.dart'

引用:
import 'dart_util.dart'

三方库

三方库网站

1、创建 pubspec.yaml文件 //这个文件像podfile和gradle

2、依赖库

name: 一般是你工程名
description: A new Flutter project.
dependencies:
  http: 版本 // 去三方库网站 - 库 - installing - dependencies

3、加载依赖

cd到yaml文件路径:pub get

新生成的三个文件不用管:oubspec.lock .dart_tool .packages

4、引用库

import 'package:xxx'

三方库网站 - 库 - readme - using

上一篇 下一篇

猜你喜欢

热点阅读