This article introduced the Dart environment and Dart syntax, including variables and constants, data types, functions, operators, classes, generics, and more.
The installation
-
Download the installation package from Dart for Windows (gekorm.com) to install the Dart SDK.
-
Install the Dart and Code Runner plug-ins in VSCode.
-
Create a new.dart file and print “Hello dart!” :
void main() {
print('Hello dart! ');
}
Copy the code
Run Code:
Hello dart!
Copy the code
Variables and constants
variable
Dart variable declarations have three keywords: var, Dynamic, and Object.
Dart, like JS, can declare a variable without a pre-defined variable type, or it can declare a variable with a type in front of it:
var a = 114514;
String str = 'this is string';
Copy the code
After declaring a variable using these two methods, the variable type cannot be changed later.
var a = 114514;
a = '12345'; / / an error
Copy the code
Using dynamic to declare variables makes it possible to not check the type at compile time, just like in JavaScript:
dynamic str = 'this is string';
str = 114514;
print(str);
Copy the code
constant
Use const and final definitions.
const PI = 3.14;
Copy the code
Const needs to be a compile-time constant, and final does not:
const constDateTime = DateTime.now(); / / an error
final finalDateTime = DateTime.now();
Copy the code
The data type
The numerical
The numeric type num contains subclasses int and double.
String
The Dart string is a sequence of utF-16 encoded characters.
Expressions can be inserted into a string using the ${expression} syntax.
Strings can be compared by ==.
bool
In if and assert expressions, their values must be of type bool. The default value is null instead of false.
List
List is like an array. By default, it receives type Dynamic and can add any object to it:
List list = [1.2.3];
Copy the code
Common properties and methods:
Reversed: toList() isEmpty: isEmpty; isNotEmpty: isNotEmpty Add (value) add(value) add(list) add(value) add(list) add(value) add(list) add array indexOf(value) Incoming value removeAt (index) to delete, incoming fillRange index value (value) startIndex endIndex, modify, [parameters 1, 2) data to modify 3 insert for a parameter (index, value); InsertAll (index,list) insertAll(index,list) insert list toList() other types convert toList join list converts to String split String converts toList ForEach map where any every these methods can also be used in most sets and mapsCopy the code
Set
Set indicates that the objects in the container are unique and sorted in the order in which they were added. A Set is an unordered and de-duplicated Set, so it has no index value.
Set set = {'a'.'b'.'a'.'c'};
print(set); // {a, b, c}
print(set.toList()); // [a, b, c]
Copy the code
Map
Maps are sorted in the order in which they are added.
Map map = {'foo': 'apple'.'bar': 'banana'};
print(map); // {foo: apple, bar: banana}
print(map.keys.toList()); // [foo, bar]
print(map.values.toList()); // [apple, banana]
map.addAll({'baz':'pear'});
map.remove("baz");
print(map.containsValue("apple")); // true
Copy the code
A way to loop data
ForEach, map, where, any, every
List: for, for... ForEach: List List =["apple", "banana", "pear"]; list.forEach((value){ print(value); List List =["apple", "banana", "pear"]; List newList = list.map((value){ return value + "1"; }).toList(); print(newList); // [apple1, banana1, pear1] WHERE: List List = [1, 2, 3, 4, 5]; List newList = list.where((value){ return value > 3; }).toList(); print(newList); // [4, 5] any: true bool b = list. Any ((value){return value > 3; }); print(b); List Map: forEach: Map person = {"name": "Jack", "age": 20,}; person.forEach((key, value){ print("$key - $value"); // name - Jack age - 20 });Copy the code
function
Like JS, functions are also objects of type Function. So a function can also be the value of a variable when it’s an argument or a return value.
Support for using the => abbreviation syntax, unlike ES6 arrow functions, where the arrow can only point to the return value of the function:
String hello(var name) => 'hello $name';
/ / equivalent to the
String hello(var name){
return 'hello $name';
}
Copy the code
If no value is returned, the default value is null.
The entry function
The entry function is main, and void can be omitted if there is no return value.
Optional parameters
- Optional named parameter
A named parameter is enclosed in curly braces and can have a default value, or null if no default value is specified:
String add({var a, var b = 1}) = >'$a' + '$b';
var a = add(b: 2);
print(a); // null2
Copy the code
- Optional position parameter
Non-mandatory parameters can be set inside square brackets. The default value can be added or not. The default value is null:
String add(var a, [var b = 1]) = >'$a' + '$b';
var a = add(1);
print(a); / / 11
Copy the code
Anonymous functions
A function that omits its name:
var func = (a, b) => a + b;
print(func(1.2)); / / 3
Copy the code
closure
The concept of closures is very important in JS, which will not be repeated here, and will be explained in a later article.
The operator
Conditional operator? .
In the following example, null is returned if p is null, and p.name is returned if p is not null:
class Person{
var name;
}
void main() {
var p = Person();
print(p? .name);// null
}
Copy the code
Take the divisible~ /
There is only more rounding function than /.
Type of operationas
.is
. is!
As is used to convert types, is, is! Used to determine the type:
num n1 = 1;
int n2 = n1 as int;
if(n2 is int) {print('n2 is int')}Copy the code
Sentenced to empty??
If a is empty, then b = 1; Conversely, b = a:
void main() {
var a;
var b = a ?? 1;
print(b);
}
Copy the code
cascade.
Equivalent to a chain call, allowing a series of operations on the same object.
Process control
As in other languages, this is omitted.
class
All objects in Dart are instances of a class that extends from the Object class.
The constructor
import 'dart:math';
/ / define the class
class Point {
num x = 0, y = 0;
// Point(this.x, this.y); / / the constructor
/ / or
Point(x, y) {
this.x = x;
this.y = y;
print('This is a constructor that fires on instantiation');
}
// Instance method
num distanceTo(Point other) {
var dx = x - other.x;
var dy = y - other.y;
return sqrt(dx * dx + dy * dy);
}
}
main() {
// Call the class constructor. New can be omitted
Point p1 = new Point(1.2); // This is the constructor, which is triggered on instantiation
Point p2 = Point(3.4); // This is the constructor, which is triggered on instantiation
// Call the class method
print(p1.distanceTo(p2)); / / 2.8284271247461903
}
Copy the code
Due to the nature of Dart 2.12, writing the constructor like this will return an error:
class Point {
num x, y;
Point(x, y) { // Non-null instance field 'x' must be initialized
// Try adding an initializer, or add a field initializer to the constructor, or mark it
this.x = x;
this.y = y; }}Copy the code
Dart doesn’t know if you assigned variable values for x and y because of space safety. Dart-non-nullable instance field must be initialized – Stack Overflow dart-non-nullable instance field must be initialized – Stack Overflow
One solution:
class Point {
num? x, y;
Point(x, y) {
this.x = x;
this.y = y; }}Copy the code
num? Represents a nullable type, indicating that the value of a variable can be null.
You can use named constructors to implement multiple constructors for a class, or use named constructors to semantic your code, as was the datetime.now () constructor previously used.
Use the redirection constructor to call other constructors with colons.
class Point {
num? x;
num? y;
Point.initX(y) { // Name the constructor
this.x = 2;
this.y = y;
}
Point.redirctor(num x) : this(x, 0); // Redirect the constructor
}
main() {
Point p1 = Point.initX(2);
print('${p1.x}.${p1.y}'); / / 2, 2
Point p2 = Point.redirctor(1);
print('${p2.x}.${p2.y}'); / / 1, 0
}
Copy the code
More and more code leads to less and less maintenance, so we need to separate classes into files and import libraries using imports where needed.
// lib\Point.dart
class Point {
num x = 0, y = 0;
Point(this.x, this.y);
}
// main.dart
import 'lib/Point.dart';
main(){
/ /...
}
Copy the code
Class and member visibility
Visibility in Dart is measured in library, and each Dart file is a library.
Use _ to represent a private property of a property or method, the Java equivalent of privite.
class Point {
num _x = 0, _y = 0;
Point(this.x, this.y);
}
Copy the code
The private attribute takes effect only when it is detached into a file.
Getter and setter
Each variable has its default getter and setter methods, and final variables are only readable, with only getter methods.
In Dart, methods cannot be overloaded.
class Rect {
late num width, height;
Rect(this.width, this.height);
area() {
return this.width * this.height;
}
// getter
get area1 {
return this.width * this.height;
}
// setter
set height2(value) {
this.height = value;
}
}
main() {
Rect r1 = Rect(1.2);
print(r1.area()); / / 2
print(r1.area1); / / 2
r1.height2 = 3;
print(r1.area1); / / 3
}
Copy the code
Initialization list
Initializing lists is done before instantiation:
class Rect {
late num width, height;
// Rect(this.width, this.height); Cannot be used simultaneously
Rect()
: width = 2,
height = 3 {
print('in class');
print(this.width * this.height);
}
}
main() {
Rect r1 = Rect();
print('in main');
}
// Output the result
// in class
// in main
/ / 6
Copy the code
Static Static member
Static variables and methods can be accessed through a class, not an instance of a class.
class Person {
static String name = 'Jackie';
static void show() {
print(name);
}
}
main() {
print(Person.name); //Jackie
Person.show(a);// Jackie
}
Copy the code
Static methods cannot access non-static members, and non-static methods can access static members.
class Person {
static String name = 'Jackie';
static show() {
print(name);
}
showInfo() {
print(name);
show(a); } } main() { Person p = Person(); p.showInfo();// Jackie Jackie
}
Copy the code
inheritance
-
A subclass inherits its parent class using the extends keyword;
-
A subclass inherits visible attributes and methods from its parent class except for constructors.
-
A subclass can duplicate the methods of its parent class.
class Person {
late String name;
late int age;
Person(this.name, this.age);
work() {
print('$name is working.'); }}class Web extends Person {
late String sex;
// Subclass constructor
Web(String name, int age, String sex) : super(name, age) {
this.sex = sex;
}
// Subclasses can override methods of their parent class
@override // Override the parent class method, select write
work() {
print('$name is working 996.');
}
}
main() {
Web w = Web('Tom'.20.'male');
print(w.sex); // male
w.work(); // Tom is working 996.
}
Copy the code
An abstract class
Dart abstract classes are used to define standards, and subclasses can inherit abstract classes or implement abstract class interfaces.
- The abstract class passes
abstract
Keyword to define. - Methods that have no method body in Dart are called abstract methods.
- If a subclass inherits an abstract class, it must implement its abstract methods.
- If you use an abstract class as an interface implementation, you must implement all properties and methods defined in the abstract class.
- Abstract classes cannot be instantiated, only subclasses that inherit from them can.
The difference between extends and implements:
- If we want to reuse methods from an abstract class, and we want to constrain our own class with an abstract method, we use it
extends
Inherit abstract classes. - If you’re just using abstract classes as a standard
implements
Implement abstract classes.
abstract class Person {
late String name;
late int age;
Person(this.name, this.age);
work(); // Abstract methods
}
class Employee extends Person {
Employee(String name, int age) : super(name, age);
@override
work() {
print('$name is working 996.'); }}class Employee2 extends Person {
Employee2(String name, int age) : super(name, age);
@override
work() {
print('$name is working 669.');
}
}
main() {
Person e = Employee('Tom'.20);
e.work(); // Tom is working 996.
// Person p = Person(); // The abstract class cannot be instantiated
Person e2 = Employee2('Jerry'.20);
e2.work(); // Jerry is working 669.
}
Copy the code
polymorphism
Is a reference that assigns an instance of a subclass to a parent class, allowing a pointer of a subclass type to be assigned to a pointer of a parent class type. The same function call may have different execution effects.
Polymorphism is when a parent class defines a method and lets its subclasses implement it, each of which behaves differently.
In the example above, both the Employee and Employee2 classes are polymorphic.
interface
Dart also has interfaces, but they are different from Java.
Dart interfaces do not have the interface keyword. Instead, ordinary or abstract classes can be implemented as interfaces using the implements keyword.
If the class is ordinary, all the methods of attributes in ordinary and abstract classes need to be overridden. Because abstract classes can define abstract methods and ordinary classes cannot, it is recommended to use abstract classes to define interfaces.
abstract class Db {
late String uri;
add(String data);
}
class Mysql implements Db {
@override
late String uri;
Mysql(this.uri);
@override
add(String data) {
print('This is Mysql. ' + '$data');
}
}
main() {
Mysql m = Mysql('xxx');
m.add('123');
}
Copy the code
Interfaces are separated into different files:
// lib\Db.dart
abstract class Db {... }// lib\Mysql.dart
import 'lib/Db.dart';
class Mysql implements Db {... }// main.dart
import 'lib/Mysql.dart'; main() {... }Copy the code
A class can implement multiple interfaces
class C implements A.B {
// A, B interface all properties and methods
}
Copy the code
Mixins
Class does not implement multiple inheritance. Mixins, unlike inheritance and interfaces, can implement functions similar to multiple inheritance:
class C extends A.B {} / / an error
class C with A.B {... }/ /)
Copy the code
- Classes that are Mixins can only inherit from Object, not from other classes.
- Classes that are Mixins cannot have constructors.
- A class can Mixins multiple Mixins classes.
- Mixins are far from being an inheritance or an interface, but rather an entirely new feature.
class A {... }class B extends A {... }class C {... }class D with B.c {... }/ / an error
class D extends A with B.C {... }/ /)
Copy the code
The last class overwrites the previous class:
class C with A.B {... }// B's method overwrites A
class D extends A with B.C {... }// B's method overwrites A,
// C's method overwrites A and B
Copy the code
The generic
Generics support for non-specific data types makes methods, classes, and interfaces reusable.
Generic method
T getData<T>(T value) {
return value;
}
main() {
print(getData<num> (123)); / / 123
print(getData<String> ('Jack')); // Jack
}
Copy the code
A generic class
// Call the generic class
List list = List.filled(2.' ');
list[0] = 'Tom';
list[1] = 12;
print(list); // [Tom, 12]
// Require that the data passed in be of type String
List list1 = List<String>.filled(2.' ');
list1[0] = 'Tom';
list1[1] = 'Jerry';
print(list1); // [Tom, Jerry]
// Define generic classes
class MyList<T> {
List list = <T>[];
add(T value) {
this.list.add(value);
}
List getList() {
returnlist; }}Copy the code
A generic interface
abstract class Cache<T> {
getByKey(String key);
setByKey(String key, T value);
}
class MemoryCache<T> implements Cache<T> {
@override
getByKey(String key) {
return null;
}
@override
setByKey(String key, T value) {
print("MemoryCache key=${key} value=${value}"); }}void main() {
MemoryCache mc = MemoryCache<Map> (); mc.setByKey('index', {"name": "Jack"."age": 20}); // MemoryCache key=index value={name: Jack, age: 20}
}
Copy the code
The class library
There are three main types of libraries in Dart:
- Our custom library
import 'lib/class.dart';
Copy the code
- System built-in library
import 'dart:math';
Copy the code
- Pub A library in the package management system
pub.dev/packages
pub.flutter-io.cn/packages
pub.dartlang.org/flutter
- You need to create a new pubspec.yaml in your project root directory
- Configure the name, description, dependencies, and so on in the pubspec.yaml file
- Running on the console
pub get
Download the package locally - Project introduction into the library
import 'package:http/http.dart' as http;
Use as to rename the library to prevent name duplication:
import 'package:http/http.dart' as http;
Copy the code
If you only need to use some of the features in the library, you can use the show or hide partial import methods:
import 'dart:math' show max;
Copy the code
The Dart 2.12
Null Safety
Null Safety can help developers avoid bugs that are difficult to detect in everyday development and can improve performance.
int a = 123;
a = null; // A Null value cannot be assigned to a variable of type int
Copy the code
Type followed by? Indicates that the change is nullable:
int? a = 123;
a = null;
List<int>? l=[1.2.3];
l=null;
print(l); // null
String? getData(value) {
if(value ! =null) {
return 'This is a string.';
}
return null;
}
Copy the code
Type assertion! Determines whether a variable is empty and throws an exception if it is. In the following example, an exception is thrown because STR is empty:
void main() {
String? str = 'String';
str = null;
print(str! .length);// Null check operator used on a null value
}
Copy the code
void printLength(String? str) {
try {
print(str! .length); }catch (e) {
print("str is null"); }}void main() {
printLength(null); // str is null
}
Copy the code
late
The keyword
The late keyword is used to delay initialization. The following class does not have a constructor. If the late keyword is not present, an error will be reported.
class Person {
late String name;
void setInfo(String name) {
this.name = name;
}
String getInfo() {
return "The ${this.name}"; }}void main(args) {
Person p = Person();
p.setInfo("Jack");
print(p.getInfo()); // Jack
}
Copy the code
required
The keyword
Required is a built-in modifier that allows any named parameter (function or class) to be marked as needed so that it is not null. Optional parameters must have a required or default value.
String printInfo(String name, {int age = 20.String sex = "male"{})// ...
}
String printInfo2(String name, {required int age, required String sex}) {
// ...
}
Copy the code