Learn Dart language quickly

Dart language

1. In Dart, everything is an Object, and all objects are instances of class. Even numeric types, methods and even null are objects, and all objects inherit from Object

2. Although Dart is a strongly typed language, variable types are optional because Dart can automatically infer variable types

3.Dart supports templates. List , represents an integer data list, and list , is a list of objects, in which any object can be loaded

4.Dart supports top-level methods (such as main method), class methods or object methods. At the same time, you can also create methods inside the methods

5.Dart supports top-level variables, class variables or object variables

6. Unlike Java, Dart does not have keywords such as public protected private. If a variable is underlined () At the beginning, it means that this variable is private in the library. See here for details

7. Variables in dart can start with letters or underscores followed by any combination of characters or numbers

 

variable

Variable definition

The following code is the method of defining variables in Dart:

main() {
  var a = 1;
  int b = 10;
  String s = "hello";
  dynamic c = 0.5;
}

You can explicitly specify the type of a variable, such as int bool String, or declare a variable with var or dynamic. Dart will automatically infer its data type.

Default value of variable

Note: variables without initial values will have a default value of null

final and const

If you never want to change a variable, use final or const instead of var or other types. A variable modified by final can only be assigned once. A variable modified by const is a compile time constant (const constant is also a final constant without doubt). It can be understood as follows: the variable modified by final is immutable, while the variable modified by const represents a constant.

Note: instance variables can be final but not const

The following is a code Description:

var count = 10; 
final Num = count;  // final can only be assigned once
const Num1 = 10; // const assignment must be a compile time constant

Difference between final and const:

Difference 1: final requires that variables can only be initialized once, and does not require that the assigned value must be a compile time constant, which can be constant or not. const requires initialization at declaration time, and the assignment must be a compile time constant.

Difference 2: final is lazy initialization, that is, it is initialized before the first use at runtime. const determines the value at compile time.

 

Built in data type

Dart has the following built-in data types:

  1. numbers
  2. strings
  3. booleans
  4. Lists (or arrays)
  5. maps
  6. runes (characters of UTF-32 character set)
  7. symbols

The following code is used to demonstrate the above data types:

main() {
  // numbers
  var a = 0;
  int b = 1;
  double c = 0.1;

  // strings
  var s1 = 'hello';
  String s2 = "world";

  // booleans
  var real = true;
  bool isReal = false;

  // lists
  var arr = [1, 2, 3, 4, 5];
  List<String> arr2 = ['hello', 'world', "123", "456"];
  List<dynamic> arr3 = [1, true, 'haha', 1.0];

  // maps
  var map = new Map();
  map['name'] = 'zhangsan';
  map['age'] = 10;
  Map m = new Map();
  m['a'] = 'a';

  //runes, which is used in Dart to obtain the characters of UTF-32 character set. The codeUnitAt and codeUnit properties of String can obtain the characters of UTF-16 character set
  var clapping = '\u{1f44f}';
  print(clapping); // Printed is the expression of clapping emoji

  // symbols
  print(#s == new Symbol("s")); // true
}

 

function

Return value of function

Dart is an object-oriented programming language, so even if a Function is an object, it also has a type of Function, which means that the Function can be assigned to a variable or passed to another Function as a parameter. Although dart recommends adding a return value to the Function, the Function without a return value can also work normally. In addition, you can use = > instead of the return statement, such as the following code:

// Declare return value
int add(int a, int b) {
  return a + b;
}

// Do not declare return value
add2(int a, int b) {
  return a + b;
}

// =>Is short for return statement
add3(a, b) => a + b; 

main() {
  print(add(1, 2)); // 3
  print(add2(2, 3)); // 5
  print(add3(1, 2)); // 3
}

 

Named parameter, position parameter, parameter default value

Named parameters

sayHello({String name}) {
  print("hello, my name is $name");
}

sayHello2({name: String}) {
  print("hello, my name is $name");
}

main() {
  // Print hello, my name is zhangsan
  sayHello(name: 'zhangsan');

  // Print hello, my name is wangwu
  sayHello2(name: 'wangwu');
}

It can be seen that when defining named parameters, you can declare parameters in {type paramName} or {paramName: type}. When calling named parameters, you need to call them in the form of funcName(paramName: paramValue).

The parameters of named parameters are not necessary, so in the above code, if you call sayHello() without any parameters, it is also possible, but the final printed result is: hello, my name is null. In the development of fluent, you can use the @ required annotation to identify a named parameter, which means that the parameter is necessary. If you do not pass it, you will report an error, such as the following code:

const Scrollbar({Key key, @required Widget child})

Location parameters

The parameter enclosed in brackets [] is the position parameter of the function, which means that the parameter can be passed or not. The position parameter can only be placed at the end of the parameter list of the function, as shown in the following code:

sayHello(String name, int age, [String hobby]) { // There can be multiple location parameters, such as [String a, int b]
  StringBuffer sb = new StringBuffer();
  sb.write("hello, this is $name and I am $age years old");
  if (hobby != null) {
    sb.write(", my hobby is $hobby");
  }
  print(sb.toString());
}

main() {
  // hello, this is zhangsan and I am 20 years old
  sayHello("zhangsan", 20);
  // hello, this is zhangsan and I am 20 years old, my hobby is play football
  sayHello("zhangsan", 20, "play football");
}

Parameter defaults

You can set default values for named parameters or location parameters, as shown in the following code:

// Default values for named parameters
int add({int a, int b = 3}) { // Cannot be written as: int add({a: int, b: int = 3})
  return a + b;
}

// Default values for location parameters
int sum(int a, int b, [int c = 3]) {
  return a + b + c;
}

main() function

Whether in Dart or fluent, a top-level main() function must be required. It is the entry function of the whole application. The return value of the main() function is void, and there is an optional parameter. The parameter type is List.

Functions as a class of objects

You can pass a function as a parameter to another function, such as the following code:

printNum(int a) {
  print("$a");
}

main() {
  //  Print in sequence:
  //  1
  //  2
  //  3
  var arr = [1, 2, 3];
  arr.forEach(printNum);
}

You can also assign a function to a variable, such as the following code:

printNum(int a) {
  print("$a");
}

main() {
  var f1 = printNum;
  Function f2 = printNum;
  var f3 = (int a) => print("a = $a");
  f1(1);
  f2(2);
  f3(6);
}

Anonymous function

Most functions have names, such as main() printName(), but you can also write anonymous functions. If you are familiar with Java, you will not be unfamiliar with the following Dart Code:

test(Function callback) {
  callback("hello");
}

main() {
  test((param) {
    // Print hello
    print(param);
  });
}

Anonymous functions are similar to interfaces in Java. They are often used when the parameter of a function is a function.

Function return value

All functions have return values. If no return statement is specified, the return value of the function is null.

 

operator

The operators in Dart are similar to those in Java, such as + + a = = B? A: B, but there are also some operators that are different from Java. The following is a code Description:

main() {
  // Same operator operation as Java

  int a = 1;
  ++a;
  a++;
  var b = 1;
  print(a == b);  // false
  print(a * b); // 3
  bool real = false;
  real ? print('real') : print('not real'); // not real
  print(real && a == b); // false
  print(real || a == 3); // true
  print(a != 2); // true
  print(a <= b); // false
  var c = 9;
  c += 10;
  print("c = $c"); // c = 19
  print(1<<2); // 4

  // Operator operation different from Java

  // The is operator is used to determine whether a variable is a certain type of data
  // is! Is to judge that the variable is not a certain type of data
  var s = "hello";
  print(s is String); // true
  var num = 6;
  print(num is! String); // true

  // ~/Is the rounding operator. If / is used, it is a division operation without rounding
  int k = 1;
  int j = 2;
  print(k / j); // 0.5
  print(k ~/ j); // 0

  // The as operator is similar to the cast operation in Java, which casts an object into a type
  (emp as Person).teach();

  // ??= Operator if= If the variable in front of the operator is null, it will be assigned; otherwise, it will not be assigned
  var param1 = "hello", param2 = null;
  param1 ??= "world";
  param2 ??= "world";
  print("param1 = $param1"); // param1 = hello
  print("param2 = $param2"); // param2 = world

  // ?. operator
  var str1 = "hello world";
  var str2 = null;
  print(str1?.length); // 11
  print(str2?.length); // null 
  print(str2.length); // report errors
}

.. Operator (cascading operation)

If you are familiar with the builder pattern in Java, the one in Dart Operators are also easy to understand. First look at the following code:

class Person {
  eat() {
    print("I am eating...");
  }

  sleep() {
    print("I am sleeping...");
  }

  study() {
    print("I am studying...");
  }
}

main() {
  // Print in sequence
  //  I am eating...
  //  I am sleeping...
  //  I am studying...
  new Person()..eat()
      ..sleep()
      ..study();
}

As you can see, use When you call an object's method (or member variable), the return value is the object itself, so you can continue to use Call other methods of this object, which is similar to the build er mode in Java. Each time a property is built, a this object is returned.

control flow

The if / else switch for /while try / catch statement is similar to that in Java. The try / catch statement may be slightly different. The following is a code Description:

main() {
  // if else statement
  int score = 80;
  if (score < 60) {
    print("so bad!");
  } else if (score >= 60 && score < 80) {
    print("just so so!");
  } else if (score >= 80) {
    print("good job!");
  }

  // switch Statements 
  String a = "hello";
  // The data type in the case statement must be consistent with that in switch
  switch (a) {
    case "hello":
      print("haha");
      break;
    case "world":
      print("heihei");
      break;
    default:
      print("WTF");
  }

  // for statement
  List<String> list = ["a", "b", "c"];
  for (int i = 0; i < list.length; i++) {
    print(list[i]);
  }
  for (var i in list) {
    print(i);
  }
  // The arrow function arguments here must be enclosed in parentheses
  list.forEach((item) => print(item));

  // while statement
  int start = 1;
  int sum = 0;
  while (start <= 100) {
    sum += start;
    start++;
  }
  print(sum);

  // try catch statement
  try {
    print(1 ~/ 0);
  } catch (e) {
    // IntegerdivisionByZeroException
    print(e);
  }
  try {
    1 ~/ 0;
  } on IntegerdivisionByZeroException { // Catch an exception of the specified type
    print("error"); // Print out error
  } finally {
    print("over"); // Print out over
  }
}

 

Class

Class definition and construction method

Classes in Dart have no access control, so you don't need to modify member variables or member functions with private, protected, public, etc. a simple class is shown in the following code:

class Person {
  String name;
  int age;
  String gender;
  Person(this.name, this.age, this.gender);
  sayHello() {
    print("hello, this is $name, I am $age years old, I am a $gender");
  }
}

The above Person class has three member variables, a constructor and a member method. What seems strange is the constructor of Person. The three parameters passed in are this XXX, and there is no method body wrapped in curly braces {}. This syntax is Dart's unique and concise method declaration method, which is equivalent to the following code:

Person(String name, int age, String gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
}

To call the member variable or member method of the Person class, you can use the following code:

var p = new Person("zhangsan", 20, "male");
  p.sayHello(); // hello, this is zhangsan, I am 20 years old, I am a male
  p.age = 50;
  p.gender = "female";
  p.sayHello(); // hello, this is zhangsan, I am 50 years old, I am a female

In addition to having the same constructor as the class name, you can also add a named constructor, as shown in the following code:

class Point {
  num x, y;
  Point(this.x, this.y);
  // Class naming and construction method
  Point.origin() {
    x = 0;
    y = 0;
  }
}

main() {
  // Call the named constructor origin() of the Point class
  var p = new Point.origin();
  var p2 = new Point(1, 2);
}

Dart uses the extends keyword to inherit classes. If a class has only named construction methods, you should pay attention to the following code when inheriting:

class Human {
  String name;
  Human.fromjson(Map data) {
    print("Human's fromjson constructor");
  }
}

class Man extends Human {
  Man.fromJson(Map data) : super.fromJson(data) {
    print("Man's fromJson constructor");
  }
}

Since the Human class has no default constructor and only one named constructor fromjason, when the Man class inherits the Human class, it is necessary to call the fromjason method of the parent class for initialization, and Man.com must be used fromJson(Map data) : super. From Jason (data) instead of writing super in curly braces like Java.

Sometimes you just call another constructor of a class in its constructor. You can write this as follows:

class Point {
  num x, y;
  Point(this.x, this.y);
  // The named constructor calls the default constructor
  Point.alongXAxis(num x) : this(x, 0);
}

Member method of class

A member method of a class is a function that provides some behavior for the class. In the above code, there are already definitions of member methods of some classes. These definitions are very similar to Java. You can provide getter/setter methods for member variables of a class, as shown in the following code:

class Rectangle {
  num left, top, width, height;

  // The construction method passes in several parameters: left, top, width and height
  Rectangle(this.left, this.top, this.width, this.height);

  // Right and bottom two member variables provide getter/setter methods
  num get right => left + width;
  set right(num value) => left = value - width;
  num get bottom => top + height;
  set bottom(num value) => top = value - height;
}

Abstract classes and abstract methods

If you use abstract to modify a class, it is an abstract class. There can be abstract methods and non abstract methods in the abstract class. The abstract method has no method body and needs to be implemented by subclasses, as shown in the following code:

abstract class Doer {
  // Abstract methods have no method body and need subclasses to implement
  void doSomething();
  // Common method
  void greet() {
    print("hello world!");
  }
}

class EffectiveDoer extends Doer {
  // Implements the abstract method of the parent class
  void doSomething() {
    print("I'm doing something...");
  }
}

Operator overloading

Dart has an operator overloading syntax similar to that in C + +. For example, the following code defines a vector class that overloads the + - operation of vectors:

class Vector {
  num x, y;
  Vector(this.x, this.y);
  Vector operator +(Vector v) => new Vector(x + v.x, y + v.y);
  Vector operator -(Vector v) => new Vector(x - v.x, y - v.y);
  printVec() {
    print("x: $x, y: $y");
  }
}

main() {
  Vector v1 = new Vector(1, 2);
  Vector v2 = new Vector(3, 4);
  (v1 - v2).printVec(); // -2, -2
  (v1 + v2).printVec(); // 4, 6
}

Enumeration class

Use enum keyword to define an enumeration class. The syntax is similar to that of Java. The code is as follows:

enum Color { red, green, blue }

mixins

mixins is a way to reuse the code in the class, such as the following code:

class A {
  a() {
    print("A's a()");
  }
}

class B {
  b() {
    print("B's b()");
  }
}

// Use the with keyword to indicate that class C is a mixture of class A and class B
class C = A with B;

main() {
  C c = new C();
  c.a(); // A's a()
  c.b(); // B's b()
}

Static member variables and static member methods

// Static member variables and static member methods of class
class Cons {
  static const name = "zhangsan";
  static sayHello() {
    print("hello, this is ${Cons.name}");
  }
}

main() {
  Cons.sayHello(); // hello, this is zhangsan
  print(Cons.name); // zhangsan
}

 

Generics

Both Java and C + + languages have generics, and Dart language is no exception. Using generics has many advantages, such as:

Specifying generic types correctly produces better generated code. Generics can reduce the complexity of code

Dart's built-in data type List is a generic data type. You can insert any data type you want into the List, such as integer, string, Boolean, etc

 

Dart Library (Libraries)

Dart currently has many libraries for developers. Many functions do not need to be implemented by developers themselves. They only need to import the corresponding package. Use the import statement to import a package, such as the following code:

import 'dart:html';

If you want to import a code file written by yourself, use the relative path. For example, there is a demo Dart file, and there is a util Dart file, the file code is as follows:

// util.dart file content

int add(int a, int b) {
  return a + b;
}

In demo In the dart file, if you want to reference util Dart file, imported in the following way:

// demo.dart

import './util.dart';

main() {
  print(add(1, 2));
}

You can use the as keyword to set a prefix or alias for an imported package, such as the following code:

import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;

// Uses Element from lib1.
Element element1 = Element();

// Uses Element from lib2.
lib2.Element element2 = lib2.Element();

You can also use the show hide keyword to import some functions in a package when importing a package, such as the following code:

// Import foo only
import 'package:lib1/lib1.dart' show foo;

// Import all parts except foo
import 'package:lib2/lib2.dart' hide foo;

Using deferred as when importing a package allows the package to be loaded lazily. The lazily loaded package will only be loaded when the package is used, not at the beginning. For example, the following code:

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

PPT template downloadhttps://redbox.wode007.com

asynchronous

Dart provides asynchronous operations like async await in ES7, which are often encountered in the development of fluent. For example, asynchronous knowledge is required for network or other IO operations, file selection, etc.

Async and await often appear in pairs. If there are time-consuming operations in a method, you need to set the method to async and add await keyword to the time-consuming operations. If the method has a return value, you need to insert the return value into Future and return it, as shown in the following code:

Future checkVersion() async {
  var version = await lookUpVersion();
  // Do something with version
}

The following code uses Dart to obtain data from the network and print it out:

import 'dart:async';
import 'package:http/http.dart' as http;

Future<String> getNetData() async{
  http.Response res = await http.get("http://www.baidu.com");
  return res.body;
}

main() {
  getNetData().then((str) {
    print(str);
  });
}

Tags: Front-end

Posted by drfate on Thu, 05 May 2022 15:10:29 +0300