Dart(一):Dart入门

Dart入门

    • Dart安装
    • 创建项目
    • 安装依赖(以`http`为例)
      • 依赖库查询地址
      • 添加依赖
      • 编写运行示例
    • dart常用命令
    • 引用核心库、自定义库、第三方库
    • 数据类型
      • Numbers (int, double)
      • Strings (String)
      • Booleans (bool)
      • Lists (List)
      • Maps (Map)
      • Sets (Set)
      • Null (null)
      • Records ((value1, value2, ...))
      • Runes (Runes)
      • Symbols (Symbol)
    • 类型判断
    • 单引号、双引号、三引号
    • 运算符
      • 除以取整(`~/`、`~/=`)
      • 取余(`%`、`%=`)
      • 如果空(`??`、`??=`)
      • 判断类型(`is`、`is!`)
      • 类型断言(`as`)
      • 条件成员访问(`?`)
      • Null断言运算符(`!`)
      • 级联表示法(`..`)
    • `late`
    • 常量`final`和`const`
      • 相同点
      • 不同点
    • 函数
      • 基本函数
      • 可选参数函数
      • 命名参数函数
      • 箭头函数
      • 自执行函数
      • 参数必传函数
      • 示例
      • 静态属性和方法
      • 泛型
      • 多态
      • `get`和`set`
      • 多接口继承
      • `mixin`
      • 常量构造函数

Dart安装

$ brew install dart-sdk
$ dart --version

在这里插入图片描述

创建项目

$ dart create -t console dart_app
$ cd dart_app
$ dart analyze # 分析项目的Dart源代码
$ dart run ./bin/dart_app.dart # 或 dart ./bin/dart_app.dart 或 dart run

在这里插入图片描述

安装依赖(以http为例)

依赖库查询地址

https://pub.dev/

添加依赖

$ dart pub add http

在这里插入图片描述

编写运行示例

import 'dart:convert' as convert;
import 'package:http/http.dart' as http;void main() async {var url = Uri.https('www.example.com');var response = await http.get(url);if (response.statusCode == 200) {print(response.body);} else {print(response.statusCode);}
}

在这里插入图片描述

dart常用命令

# 添加依赖
$ dart pub add date_format:'^2.0.5'# 删除依赖
$ dart pub remove http# 清空全局的本地缓存
$ dart pub cache clean# 获取所有在当前工作目录下的 pubspec.yaml 文件中列出的依赖项,以及这些依赖项的 间接依赖项,必要时下载该依赖项并更新缓存
$ dart pub get# 获取当前工作目录下 pubspec.yaml 文件中列出的所有依赖项以及它们 间接依赖项 的最低版本
$ dart pub downgrade# 识别过期的包依赖项,并获得如何更新它们的建议
$ dart pub outdated# 与 dart pub get 命令一样,都是用于获取依赖项的。不同的是该命令会忽略掉任何已存在的 lockfile 文件,因此 Pub 可以获取所有依赖项的最新版本
$ dart pub upgrade

引用核心库、自定义库、第三方库

import 'dart:math'; // 核心库
import '../lib/dart_app.dart'; // 自定义库
import 'package:date_format/date_format.dart'; // 第三方库

示例

import 'dart:math'; // 引用全部方法
import 'dart:math' as Math; // 别名void main() {print(Random().nextBool());print(Math.Random().nextBool());print(max(0, 0));
}
import 'dart:math' show max; // 只引入maxvoid main() {print(max(0, 1));print(Random().nextBool()); // Error
}
import 'dart:math' hide max,Random; // 只引入除了max和Randomvoid main() {print(Point(0, 1));print(max(0, 1)); // Errorprint(Random().nextBool()); // Error
}

数据类型

int、double、String、bool、List、Map、Set、null、(value1, value2, …)、Runes、Symbol

Numbers (int, double)

void main() {var a = 123; // var会自动推断类型为intint b = 123;double c = 1;double d = 1.23;b = d; // Error: “double”类型的值不能分配给“int”类型的变量.d = b; // Error: “int”类型的值不能分配给“double”类型的变量.print(0 / 0); // NaNprint((0 / 0).isNaN); // true
}

Strings (String)

void main() {var a = "1a2b3c"; // var会自动推断类型为StringString b = "1.2b3c";print(a.length); // 6print(int.parse(a));print(double.parse(b));String c = "123.4";print(double.parse(c)); // 123.4
}

Booleans (bool)

void main() {bool a = true;bool b = false;
}

Lists (List)

void main() {List l1 = [];l1.add("Lee");l1.add("男");l1.add("你好");l1.add(18);print(l1); // [Lee, 男, 你好, 18]print(l1.first); // Lee 返回第一个元素print(l1.last); // 18 返回列表中的最后一个元素print(l1.isEmpty); // false 如果集合没有元素,则返回trueprint(l1.isNotEmpty); // true 如果集合至少包含一个元素,则返回trueprint(l1.length); // 4print(l1.reversed); // (18, 你好, 男, Lee) 以相反的顺序返回包含列表值的可迭代对象List l2 = [];print(l2.isEmpty); // trueprint(l2.isNotEmpty); // falseList l3 = ["abc"];print(l3.single); // abc 检查列表是否只有一个元素并返回它,否则抛出异常List<int> l4 = [1, 2, 3];l4.add("abc"); // Error: 无法将参数类型“String”分配给参数类型“int”List l5 = ["Lee", 18, "男", "Tom", 20, "男"];l5.remove("男"); // [Lee, 18, Tom, 20, 男]// 创建固定长度的数组List l6 = List.filled(3, "Lee"); // ["Lee", "Lee", "Lee"]l6[1] = "Tom"; // [Lee, Tom, Lee]l6.length = 4; // Error: 不允许修改数组长度l6.add("Tom"); // Error: 不允许修改数组长度l6.remove("Lee"); // Error: 不允许修改数组长度
}

Maps (Map)

void main() {Map data = {1: "一","two": 2,"three": true// a: true, // Error: 找不到变量a};print(data); // {1: 一, two: 2, three: true}print(data["two"]); // 2data["three"] = false;print(data); // {1: 一, two: 2, three: false}
}

Sets (Set)

void main() {Set data = {1, 2, 3};print(data); // {1, 2, 3}data.add(4);print(data); // {1, 2, 3, 4}
}
void main() {Set<String> data = {"苹果", "香蕉"};print(data); // {苹果, 香蕉}print(data.toList()); // [苹果, 香蕉]
}

Null (null)

空安全(null safety)

空安全会在编译期防止意外访问 null 变量的错误的产生

void main() {String name = "Lee";name = null; // Error: 无法将值“null”分配给“String”类型的变量,因为“String”不可为null
}

允许为空

void main() {String? name = "Tom";name = null;
}

Records ((value1, value2, …))

void main() {var record = (1, b: 2, c: 3, d: true, null, 5, [7], {8}, {"i": 9});print(record);      // (1, null, 5, [7], {8}, {i: 9}, b: 2, c: 3, d: true)print(record.$1);   // 1print(record.$2);   // nullprint(record.$3);   // 5print(record.$4);   // [7]print(record.$5);   // {8}print(record.$6);   // {i: 9}print(record.b);    // 2print(record.c);    // 3print(record.d);    // truevar (lat, lng) = (1000, 2000);print(lat); // 1000print(lng); // 2000
}

Runes (Runes)

void main() {Runes input = new Runes("\u{1f605}"); print(new String.fromCharCodes(input)); 
}

Symbols (Symbol)

void main() {Symbol obj = new Symbol("Lee"); print(obj); // Symbol("Lee")
}

类型判断

void main() {var a = 123;print(a is int); // trueprint(a is double); // false
}

单引号、双引号、三引号

void main() {String msg1 = '你好,我叫''Lee';String msg2 = "你好,我叫""Lee";String msg3 = '''你好,我叫Lee''';String msg4 = """你好,我叫Lee""";print(msg1); // 你好,我叫Leeprint(msg2); // 你好,我叫Leeprint(msg3); // 你好,我叫\n\tLeeprint(msg4); // 你好,我叫\n\tLee
}

运算符

除以取整(~/~/=

void main() {print(3 ~/ 2); // 1print(1.2 * 2 ~/ 1); // 2
}
void main() {var a = 123;a ~/= 2;print(a); // 61
}

取余(%%=

void main() {print(3 % 2); // 1print(1.2 * 2 % 2); // 0.3999999999999999 精度问题
}
void main() {var a = 3;a %= 2;print(a); // 1
}

如果空(????=

注意:??|| 不同

import 'dart:math';void main() {var a = Random().nextBool() ? null : 1;var b = a ?? 2;print('$a, $b'); // 1, 1 OR null, 2print(!!null || false); // Error: 无法将值“null”分配给“bool”类型的变量,因为“bool“不可为null”print(!!0 || false); // Error: 不能将“int”类型的值分配给“bool”类型的变量
}
import 'dart:math';void main() {var a = Random().nextBool() ? null : 1;a ??= 2;print(a); // 1 OR 2
}

判断类型(isis!

import 'dart:math';void main() {var a = Random().nextBool() ? "Lee" : 1;print(a is int); // false OR trueprint(a is String); // true OR falseprint(a is! bool); // true
}

类型断言(as

import 'dart:math';void main() {var str = "Hello, Lee!!!";String msg = str as String;print(msg.length); // 13var a = Random().nextBool() ? "Lee" : 1;print((a as String).length); // 3 OR Error: 类型“int”不是类型强制转换中类型“String”的子类型
}

条件成员访问(?

示例1

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><button id="confirm">Confirm</button><script src="./out.js"></script>
</body>
</html>
import 'dart:html';void main() {var confirm = querySelector('#confirm');// confirm.onClick.listen((e) => {window.alert('Confirmed!')}); // Error: 无法在“Element?”上访问属性“onClick”因为它可能为空confirm?.onClick.listen((e) => {window.alert('Confirmed!')}); // ok
}
$ dart compile js ./bin/dart_app.dart

在这里插入图片描述

示例2

import 'dart:math';void main() {String? name = Random().nextBool() ? "Lee" : null;print(name?.length); // 3 OR null
}

Null断言运算符(!

import 'dart:math';void main() {String? name = Random().nextBool() ? "Lee" : null;print(name!.length); // 3 OR Error: Null值上使用的Null检查运算符
}

级联表示法(..

class Person {String name = "Lee";int age = 18;void say(){print("$name, $age");}
}void main() {Person person = Person();person..name = "Tom"..age = 20..say(); // Tom, 20
}

late

在运行时而非编译时对变量进行约束

定义一个无初始值的非空字段

class Person {// String name; // Error: 字段“name”应初始化,因为其类型“String”不允许为nullString? name; // oklate String name; // ok
}void main() {}

常量finalconst

相同点

  1. 用来定义常量,一旦赋值不可改变,并且类型声明可以忽略
void main() {final a = "Lee";const b = "Tom";a = "AAA"; // Errorb = "BBB"; // Error
}

不同点

  1. final变量的初始值可以在编译时确定,也可以在运行时确定; const变量的初始值只能是编译时确定的值
void main() {final a = DateTime.now();const b = DateTime.now(); // Error: 不能调用需要常量表达式的非“const”构造函数
}
  1. 内存中的创建。相同的值,final变量会重复创建,const会引用同一份值
void main() {final a = {"name": "Lee"};final b = {"name": "Lee"};const c = {"name": "Lee"};const d = {"name": "Lee"};print(a == b); // falseprint(b == c); // falseprint(c == d); // true
}
  1. const变量的不可变性是嵌套的,final不是
void main() {final a = {"name": "Lee"};const b = {"name": "Lee"};a["name"] = "Tom"; // okb["name"] = "Tom"; // Error: 无法修改不可修改的映射
}
  1. const初始化必须赋值,final初始化可以先不赋值,调用前必须赋值
void main() {final a;print(a); // Error: 必须先分配最终变量“a”,然后才能使用它const b;  // Error: 必须初始化常量变量“b”
}
  1. 在类中,final可直接修饰变量;const需要使用static修饰变量
class Person {final a = DateTime.now();const b = "Lee"; // Error: 只有静态字段才能声明为常量
}

函数

基本函数

String say1(String name, int age) {String msg = "$name $age";return msg;
}// 函数表达式
Function say2 = (String name, int age) {String msg = "$name $age";return msg;
};void main() {var msg1 = say1("Lee", 18);var msg2 = say2("Tom", 20);print(msg1); // Lee 18print(msg2); // Tom 20
}

可选参数函数

String say(String name, [int? age]) {String msg = "$name $age";return msg;
}void main() {print(say("Lee")); // Lee nullprint(say("Tom", 18)); // Tom 18
}
String say(String name, [int age = 18]) {String msg = "$name $age";return msg;
}void main() {var msg = say("Lee");print(msg); // Lee 18
}

命名参数函数

String say(String name, int age, {String? sex, String? desc}) {return "$name $age $sex $desc";
}void main() {print(say("Lee", 18, sex: "男")); // Lee 18 男 nullprint(say("Lee", 18)); // Lee 18 null nullprint(say("Lee", 18, desc: "不简单啊!")); // Lee 18 null 不简单啊!print(say("Lee", 18, desc: "不简单啊!", sex: "男")); // Lee 18 男 不简单啊!
}

箭头函数

注意:只允许存在一条语句

var method1 = (String name) => {print("Hi, $name!!!")};
var method2 = (String name) => print("Hi, $name!!!");void main() {method1("Lee"); // Hi, Lee!!!method2("Tom"); // Hi, Tom!!!
}

自执行函数

var msg1 = ((String name) {return "Hi, $name!!!";
}("Lee"));var msg2 = ((String name) {return "Hi, $name!!!";
})("Tom");void main() {print(msg1); // Hi, Lee!!!print(msg2); // Hi, Tom!!!
}

参数必传函数

String say1(String name, {required int age}) {String msg = "$name $age";return msg;
}String say2(String name, {int? age}) {String msg = "$name $age";return msg;
}void main() {print(say1("Lee")); // Error: 参数“age”为必填参数print(say1("Lee", age: 18)); // Lee 18print(say2("Lee")); // Lee nullprint(say2("Lee", age: 18)); // Lee 18
}

示例

lib/dart_app.dart

// 父类-利用抽象类实现接口
abstract class IParent {late String lastName;String say(int age);
}// 子类接口,继承自父类-利用抽象类实现接口
abstract class ISub extends IParent {late String firstName;late String _fullName;
}// 父类的实现
class Parent implements IParent {late String lastName;// 父类构造方法Parent(this.lastName);String say(int age) {print("My lastName is $lastName, $age years old!!!");return lastName;}
}// 子类的实现,继承自父类
class Sub extends Parent implements ISub {late String firstName;late String _fullName;// 子类构造方法Sub(this.firstName, String lastName) : super(lastName) {_fullName = "$firstName·${this.lastName}";}// 重写say方法String say(int age) {super.say(age);String msg = "Hi, My name is $firstName·$lastName, FullName is $_fullName!!!";return msg;}
}

bin/dart_app.dart

import 'package:dart_app/dart_app.dart';void main() {Sub lee = Sub("Prosper", "Lee");print(lee.firstName); // Prosperprint(lee.lastName);  // Lee// print(lee._fullName); // Prosper·Lee 注意:同一文件下可访问; 不同文件下_fullName为私有属性,不可访问;print(lee.say(18));   // My lastName is Lee, 18 years old!!!   Hi, My name is Prosper·Lee, FullName is Prosper·Lee!!!
}

静态属性和方法

class Person {static late String name;static setName(String n){name = n;}
}void main() {Person.setName("Lee");print(Person.name); // Lee
}

泛型

class CustomList<T> {List list = <T>[];List add<T>(T value) {list.add(value);return list;}
}void main() {CustomList<String> l1 = CustomList<String>();l1.add("Lee");l1.add("Tom");print(l1.list); // [Lee, Tom]CustomList l2 = CustomList();l2.add("Lee");l2.add(18);print(l2.list); // [Lee, 18]
}

多态

允许将子类类型的指针赋值给父类类型的指针, 同一个函数调用会有不同的执行效果

class Animal {void eat() {print('Animal eating...');}
}class Cat extends Animal {void eat() {print('Cat eating...');}void run() {print('Cat running...');}
}class Dog extends Animal {void eat() {print('Dog eating...');}void run() {print('Dog running...');}
}void main() {Animal animal = Animal();Animal cat = Cat();Animal dog = Dog();animal.eat(); // Animal eating...cat.run(); // Error: Animal类中没有定义run方法;cat.eat(); // Cat eating...dog.eat(); // Dog eating...
}

getset

class Person {String name = "Lee";get GetName {return name;}set SetName(String value) {name = value;}
}void main() {Person person = Person();print(person.name);     // Leeprint(person.GetName);  // Leeperson.SetName = "Tom";print(person.name);     // Tomprint(person.GetName);  // Tom
}

多接口继承

abstract class People {void say();
}abstract class Fish {void swim();
}class Person implements People, Fish {void say() {print("say...");}void swim() {print("swim...");}
}void main() {Person person = Person();person.say();  // say...person.swim(); // swim...
}

mixin

实现多继承(报错)

class A {printA() {print("A");}
}class B {printB() {print("B");}
}class C extends A, B {} // Error: 每个类定义最多可以有一个extends子句

使用mixin

mixin class A {printA() {print("A");}say() {print("say A");}
}mixin class B {printB() {print("B");}say() {print("say B");}
}class C with B, A {}class D extends B with A {}void main() {C c = C();c.printA(); // Ac.printB(); // Bc.say();    // say A 覆盖BD d = D();d.printA(); // Ad.printB(); // Bd.say();    // say A 覆盖B
}

常量构造函数

常量构造函数是指返回不可变对象的构造函数,内存中只保留了一个对象

// 常量构造函数
class Person {final String name;const Person(this.name);
}// 非常量构造函数
class Animal {String name;Animal(this.name);
}void main() {var a = Object();var b = Object();print(identical(a, b)); // false 检查两个引用是否指向同一个对象final p1 = const Person("Lee");final p2 = const Person("Lee");final p3 = const Person("Tom");print(identical(p1, p2)); // trueprint(identical(p1, p3)); // falsefinal a1 = Animal("Lee");final a2 = Animal("Lee");final a3 = Animal("Tom");print(identical(a1, a2)); // falseprint(identical(a1, a3)); // false
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/163670.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是CCS Concepts

在撰写论文时&#xff0c;看到了CCS Concepts&#xff0c;注意这是对自己论文的分类&#xff0c;不能随便填写。 在ACM的网页"http://dl.acm.org/ccs/ccs.cfm"中选择自己论文的分类&#xff1a; 然后点击左侧的“Assign This CCS Concept”&#xff0c;再选择相关性…

Qt 4.8.6 的下载与安装

Qt 4.8.6 的下载与安装 Qt 4.8.6 的下载与安装下载并解压 MinGW 4.8.2Qt4.8.6 库的安装Qt Creator 3.3.0 的安装配置 Qt Creator测试 官方博客&#xff1a;https://www.yafeilinux.com/ Qt开源社区&#xff1a;https://www.qter.org/ Qt 4.8.6 的下载与安装 学习《Qt Creato…

js 高效生成连续递增的小数数组

简介 JavaScript 按照指定间隔生成连续递增的数组。 1. 循环生成 function generateIncrementalArray(start, end, step) {const result [];for (let i start; i < end; i step) {result.push(parseFloat(i.toFixed(1))); // 使用 toFixed() 方法限定小数位数}return r…

Rust编程基础核心之所有权(下)

1.变量与数据交互方式之二: 克隆 在上一节中, 我们讨论了变量与数据交互的第一种方式: 移动, 本节将介绍第二种方式:克隆。 如果我们 确实 需要深度复制 String 中堆上的数据&#xff0c;而不仅仅是栈上的数据&#xff0c;可以使用一个叫做 clone 的通用函数。 看下面的代码…

1.用递归求一个正整数的逆序数

#include<stdio.h>void f(int n){if(0!n){ //n是0的时候&#xff0c;退出循环 printf("%d ",n%10);f(n/10);} } int main(){f(12345);return 0; } /*void(12345) 12345不等于0 12345%105 输出 5 12345/101234void(1234) 1234不等于0 1234%104 输出 4 1…

DDD领域模式的模块层级及其依赖关系

DDD领域模型设计是一种常用的软件设计模式,它强调将业务逻辑和数据模型放在最核心的位置,以便更好地满足业务需求。在DDD领域模型设计中,应用程序被分为四个层次:用户界面层、应用服务层、领域模型层和基础设施层。 层次 用户界面层(Presentation Layer) 作为用户和应…

【Unity】2D角色跳跃控制器

最近加了学校的Nova独游社&#xff0c;本文是社团出的二面题&#xff0c;后续有时间优化下可能会做成一个二维冒险小游戏。本文主要涉及相关代码&#xff0c;参考教程&#xff1a;《勇士传说》横版动作类游戏开发教程 效果演示 【Unity】2D角色跳跃模拟器 主要实现功能&#xf…

模版方法模式-定义算法的框架

在生活中&#xff0c;很多事需要通过几个步骤才能完成。例如找工作&#xff0c;一般都包含投递简历、面试、等待结果等几个步骤。投递简历何等待结果这两个步骤大同小异&#xff0c;最大的区别在于面试这个步骤。 在软件开发中&#xff0c;有时也会遇到类似情况。某个方法的实…

SpringBoot+AOP+自定义注解,优雅实现日志记录

文章目录 前言准备阶段1、数据库日志表2、自定义注解编写3、AOP切面类编写4、业务层4.1、Service 层&#xff1a;4.2 Service 实现层&#xff1a; 5、测试 前言 首先我们看下传统记录日志的方式是什么样的&#xff1a; DeleteMapping("/deleteUserById/{userId}") …

Juniper Networks Junos OS EX远程命令执行漏洞(CVE-2023-36845)

Juniper Networks Junos OS EX远程命令执行漏洞&#xff08;CVE-2023-36845&#xff09; 免责声明漏洞描述漏洞影响漏洞危害网络测绘Fofa: body"J-web" || title"Juniper Web Device Manager" 漏洞复现1. 构造poc2. 查看文件3. 执行命令 免责声明 仅用于技…

AI系统ChatGPT程序源码+AI绘画系统源码+支持GPT4.0+Midjourney绘画

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

[ Linux Busybox ] flash_eraseall 命令解析

文章目录 相关结构体flash_eraseall 函数实现flash_eraseall 实现流程图 文件路径&#xff1a;busybox-1.20.2/miscutils/flash_eraseall.c 相关结构体 MTD 相关信息结构体 struct mtd_info_user {__u8 type; // MTD 设备类型__u32 flags; // MTD设…