The previous post introduced the cross-platform mobile development solution Flutter and the environment in which the Flutter was developed. Since Flutter was developed in the Dart language, this post documented the grammar of the Dart language.

The index The article
1 Write an open Source Chinese Client based on Flutter from 0 (1)

Flutter build | nuggets technical essay introduction and development environment
👉 2 Write an open Source Chinese Client based on Flutter from 0 (2)

Dart Grammar Basics
3 Write an open Source Chinese Client based on Flutter from 0 (3)

Introduction to Flutter & Common Widgets
4 Write an open Source Chinese Client based on Flutter from 0 (4)

Foundation of Flutter layout
5 Write an open Source Chinese Client based on Flutter from 0 (5)

Set up the overall layout framework of the App
6 Write an open Source Chinese Client based on Flutter from 0 (6)

Implementation of various static pages
7 Write an open Source Chinese Client based on Flutter from 0 (7)

App network requests and data stores
8 Write an open Source Chinese Client based on Flutter from 0 (8)

Use of plug-ins

Dart Language Introduction

Dart is a programming language developed by Google. Dart was originally designed to replace Javascript in the browser, but has since evolved into a high-quality programming language for Android, iOS, and the Web. Dart is currently available as Dart2. www.dartlang.org/

Dart is described on the Official Dart website as follows:

Developers at Google and elsewhere use Dart to create high-quality, mission-critical apps for iOS, Android, and the web. With features aimed at client-side development, Dart is a great fit for both mobile and web apps.

Dart is used by developers at Google and elsewhere to build high-quality, mission-critical applications for Android, iOS, and the Web. Dart is ideally suited for mobile and Web applications because of its client-side characteristics.

Dart language features

As Productive as you are,

Dart’s syntax is clear and concise, its tooling simple yet powerful. Sound typing helps you to identify subtle errors early. Dart has battle-hardened core libraries and an ecosystem of thousands of packages.

Dart’s syntax is clear, and its tools are simple but powerful. Sound typing helps in early identification of subtle errors. Dart has a battle-hardened core library and thousands of ecosystems.

Fast, Fast, Fast

Dart provides optimizing ahead-of-time compilation to get predictably high performance and fast startup across mobile devices and the web.

Dart provides pre-optimized compilation for predictable performance and quick startup on mobile devices and the Web.

A: It’s a Portable product.

Dart compiles to ARM and x86 code, so that Dart mobile apps can run natively on iOS, Android, and beyond. For web apps, Dart transpiles to JavaScript.

Dart can be compiled into ARM and X86 code, so Dart mobile applications can run on iOS, Android, and elsewhere. For Web applications, DART compiles to JavaScript.

Approachable

Dart is familiar to many existing developers, thanks to its unsurprising object orientation and syntax. If you already know C++, C#, or Java, you can be productive with Dart in just a few days.

Dart will be familiar to many existing developers, thanks to its surprising object positioning and syntax. If you already know C++, C, or Java, you can use Dart in just a few days.

Reactive, Reactive

Dart is well-suited to reactive programming, With support for managing short-lived objects — such as UI widgets — through Dart’s fast object allocation and generational garbage collector. Dart supports asynchronous programming through language features and APIs that use Future and Stream objects.

Dart is well suited for reactive programming, enabling Dart’s fast object allocation and garbage collector to manage ephemeral objects such as UI widgets. Dart supports asynchronous programming by using language features and apis for future and stream objects.

Dart Syntax Introduction

If you are familiar with Java, you should be able to get to know the Dart syntax fairly quickly. The Dart syntax is described in detail on the official website, but it is all in English. If you have no difficulty reading English, you can go to the official documentation.

To understand the basics of Dart syntax, we’re using Android Studio as a development tool here (you can also run code using Dartpad, which is a browser-based Dart runtime environment). If you’ve set up the Flutter development environment as described in the previous article, Then you can create the Flutter project directly in Android Studio, as shown below:

lib/main.dart
.dart
demo.dart

demo.dart

// Define a function.
printInteger(int aNumber) {
  print('The number is $aNumber.'); // Print to console.
}

// This is where the app starts executing.
main() {
  var number = 42; // Declare and initialize a variable.
  printInteger(number); // Call a function.
}
Copy the code

Then right-click in the code editing area and select Run demo.dart to Run a simple DART program, as shown below:

  1. Dart uses // for single-line comments. Dart supports both multi-line and document comments. You can read more here

  2. Int is one of the data types in Dart, as well as other built-in data types such as String List bool

  3. Console output uses the print statement

  4. Strings can be in single or double quotes, such as ‘hello’, ‘hello’

  5. String inserts can use syntax like $name or ${name}, such as the following code:

      var name = 'zhangsan';
      print("hello, I am $name");
      int a = 10, b = 20;
      print("$a + $b = ${a + b}");
    Copy the code

    If you use the ${name} approach, the braces can be expressions

  6. You may have noticed that Dart’s variable types are optional. You can specify a type for a variable, or use var to define the variable, and Dart will automatically infer the type

Important concepts

Here are some facts and concepts to keep in mind as you learn the Dart language:

  • In Dart, everything is an object, everything is an instance of class, even numeric types, methods, and even null are objects, and all objects are inheritedObject
  • Although Dart is a strongly typed language, variable types are optional because Dart can automatically infer variable types
  • Dart support paradigm,List<int>Represents a list of integers,List<dynamic>Is a list of objects that can hold any object
  • Dart supports top-level methods (e.gmainMethods), can also support class or object methods, and you can also create methods inside methods
  • Dart supports top-level variables, as well as class or object variables
  • Dart, unlike Java, does notpublic protected privateIf a variable is followed by an underscore (_), which means that the variable is private in the libraryLook here
  • Variables in Dart can start with a letter or underscore, followed by any combination of characters or numbers
  • Sometimes what matters is whether something is an expression or a statement, so the accuracy of these two words is helpful
  • The Dart tool can report two types of problems: warnings and errors. Warnings simply indicate that the code may not work, but they do not prevent the program from executing. Errors can occur at compile time or run time. Compile-time errors do not allow code to execute at all; Runtime errors cause exceptions to be thrown when code is executed.

variable

Variable definitions

The following code is how variables are defined in Dart:

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

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

The default value of the variable

Note: All variables that are not assigned initial values will have default valuesnull

Final and const

If you never want to change a variable, use final or const instead of var or other types. A variable that is final can only be assigned once. A variable that is const is a compile-time constant (const constants are also, of course, final). A final modifier is immutable, while a const modifier is a constant.

Note: Instance variables can be final but cannot be const

Here’s the code:

  final String name = 'zhangsan';
  name = 'lisi'; Const a = 0; // Final = const a = 0; a = 1; / / errorCopy the code

Difference between final and const:

  • A difference:finalRequires that variables be initialized only once, and does not require that the assigned value be a compile-time constant, which may or may not be. whileconstRequires initialization at declaration time, and assignments must be compile-time constants.
  • Difference between 2:finalIs lazy initialization, that is, initialized before the first use at runtime. whileconstThe value is determined at compile time.

Built-in data types

Dart has the following built-in data types:

  • numbers
  • strings
  • booleans
  • Lists (or arrays)
  • maps
  • Runes (characters in the UTF-32 character set)
  • symbols

The following code demonstrates each of these 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'; Dart uses runes to get the characters in the UTF-32 character set. The codeUnitAt and codeUnit attributes of String obtain the character var clapping = of the UTF-16 character set'\u{1f44f}';
  print(clapping); // Prints the symbols for the clapping emojiprint(#s == new Symbol("s")); // true
}
Copy the code

function

The return value of the

Dart is an object-oriented programming language, so even a Function is an object and has a type Function, which means that a Function can be assigned to a variable or passed as an argument to another Function. Dart recommends that you add a return value to a function, but functions that do not add a return value will work just fine. Alternatively, you can use => instead of a return statement, such as this:

Int add(int a, int b) {returna + b; } add2(int a, int b) {add2(int a, int b) {returna + b; } / / = > isreturnAdd3 (a, b) => a + b; add3(a, b) => a + b;main() {
  print(add(1, 2)); / / 3print(add2(2, 3)); / / 5print(add3(1, 2)); // 3
}
Copy the code

Named parameters, positional parameters, and parameter defaults

Named parameters

Enclosing a function’s arguments in curly braces defines named arguments, as shown in the following code:

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

As you can see, when you define a named parameter, you can declare it as {type paramName} or {paramName: type}. When you call a named parameter, you need to call it as funcName(paramName: paramValue).

The named arguments are not required, so in the above code, it is ok to call sayHello() with no arguments, but the result printed is: Hello, my name is null. In Flutter development, you can use the @Required annotation to identify a named parameter, which means that the parameter is required. If you do not pass it, an error will be reported, as in the following code:

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

Positional arguments

The arguments enclosed in brackets [] are the positional arguments of the function, indicating that they can be passed or not. Positional arguments can only be placed at the end of the argument list of the function, as shown in the following code:

SayHello (String name, int age, [String hobby]) {// There can be multiple positional arguments, for example, [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");
}
Copy the code

Parameter Default values

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

Int add({a: int, b: int = 3})returna + b; Int sum(int a, int b, [int c = 3]) {return a + b + c;
}
Copy the code

The main () function

In both Dart and Flutter, you must have a top-level main() function, which is the entry function for the entire application, with a return value of void and an optional argument of type List

.

Function as a class object

You can pass one function as an argument to another, as in the following code:

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

main() {/ / in order to print: / / 1 / / 2/3 / var arr = [1, 2, 3]; arr.forEach(printNum);
}
Copy the code

You can also assign a function to a variable, as in 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);
}
Copy the code

Anonymous functions

Most functions have names, such as main(), printName(), etc., but you can also write anonymous functions, and if you’re familiar with Java, you’ll be familiar with the following Dart code:

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

main() {
  test((param) {// Print helloprint(param);
  });
}
Copy the code

Anonymous functions are similar to interfaces in Java and are often used when a function’s argument is a function.

Function return value

All functions have a return value. If no return statement is specified, the function returns null.

The operator

The operators in Dart are similar to those in Java, such as ++a a == b b? A: b, but there are also some operators that are not quite the same as Java, as shown in the following code:

main() {// 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); // the is operator is used to determine whether a variable is a certain type of data // is! Var s = var s ="hello";
  print(s is String); // true
  var num = 6;
  print(num is! String); // trueInt k = 1; int k = 1; int j = 2;print(k / j); / / 0.5print(k ~/ j); // 0 // the as operator is similar to the Cast operation in Java, casting an object (emp as Person).teach(); / /?? The = operator if?? If the variable preceding the = operator is NULL, then the value is assigned. Otherwise, the value var param1 = is not assigned"hello", param2 = null; param1 ?? ="world"; param2 ?? ="world";
  print("param1 = $param1"); // param1 = hello
  print("param2 = $param2"); // param2 = world // ? The. Operator var str1 ="hello world";
  var str2 = null;
  print(str1? .length); / / 11print(str2? .length); // nullprint(str2.length); / / error}Copy the code

. Operators (cascading operations)

If you’re familiar with the Builder pattern in Java, Dart’s.. 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() {// I am eating... // I am sleeping... // I am studying... new Person().. eat() .. sleep() .. study(); }Copy the code

As you can see, using.. When you call a method (or member variable) on an object, the return value is the object itself, so you can then use.. Calling other methods on this object is similar to the Builder pattern in Java, which returns a this object every time a property is built.

Control process

If/else switch for /while try/catch statements are similar to those in Java. Try/catch statements may be slightly different.

main() {
  // if elseInt 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 statement String a ="hello";
  // caseThe data type in the statement must be the same as the type in the switch. Switch (a) {case "hello":
      print("haha");
      break;
    case "world":
      print("heihei");
      break;
    default:
      print("WTF"); } / /forList<String> List = ["a"."b"."c"];
  for (int i = 0; i < list.length; i++) {
    print(list[i]);
  }
  for (var i in list) {
    print(i); } list. ForEach ((item) =>print(item));

  // whileInt start = 1; int sum = 0;while (start <= 100) {
    sum += start;
    start++;
  }
  print(sum); // Try catch statement try {print(1 ~ / 0); } catch (e) { // IntegerDivisionByZeroExceptionprint(e); } try { 1 ~/ 0; } on IntegerDivisionByZeroException {/ / catch exceptions of the specified typeprint("error"); // Print error} finally {print("over"); // Print over}}Copy the code

Class (Class)

Class definitions and constructors

Dart’s classes don’t have access control, so you don’t need to modify member variables or functions with private, protected, public, etc. A simple class would look like this:

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"); }}Copy the code

The Person class above has three member variables, one constructor and one member method. What seems odd is that the Person constructor is passed in with this.xxx as the three arguments, and there is no {} enclosing the method body. This syntax is unique and concise for Dart’s constructor declaration. It is equivalent to the following code:

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

To call a member variable or a member method of the Person class, 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
Copy the code

Dart classes don’t have access control, so you can directly access an object’s member variables using obj.var.

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

class Point { num x, y; Point(this.x, this.y); // Class named constructor Point.origin() { x = 0; y = 0; }}main() {// call the named constructor of the Point class origin() var p = new point.origin (); var p2 = new Point(1, 2); }Copy the code

Dart extends a class with the extends keyword. If a class has only named constructors, you need to be careful 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"); }}Copy the code

Man.fromjson (Map data) man.fromJSON (Map data) man.fromJSON (Map data) man.fromJSON (Map data); Super.fromjson (data) instead of writing the super inside curly braces as Java does.

Sometimes you just call another constructor of a class in the constructor of that class. You can write:

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

Class member methods

A member method of a class is a function that provides some behavior for that class. You can provide getters/setters for member variables of a class by using the following code:

class Rectangle { num left, top, width, height; Rectangle(this.left, this.top, this.width, this.height); // Rectangle(this.left, this.top, this.width, this.height); Num get right => left + width;set right(num value) => left = value - width;
  num get bottom => top + height;
  set bottom(num value) => top = value - height;
}
Copy the code

Abstract classes and methods

Abstract methods can have both abstract and non-abstract methods. Abstract methods have no method body. Subclasses are required to implement them.

Abstract class Doer {// abstract class DoerdoSomething(); // The normal method voidgreet() {
    print("hello world!"); }} Class EffectiveDoer extends Doer {// this class EffectiveDoer extends DoerdoSomething() {
    print("I'm doing something..."); }}Copy the code

Operator overloading

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

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
}
Copy the code

Enumeration class

Use the enum keyword to define an enumeration class. The syntax is similar to that of Java.

enum Color { red, green, blue }
Copy the code

mixins

Mixins are a way to reuse code from a class, such as the following:

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

class B {
  b() {
    print("B's b()"); } class C = A with B;} class C = A with B;main() {
  C c = new C();
  c.a(); // A's a() c.b(); // B's b()
}
Copy the code

Static member variables and static member methods

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
}
Copy the code

Generics

Both the Java and C++ languages have generics, and Dart is no exception. There are many benefits to using generics, such as:

  • Specifying generic types correctly results in better generated code.
  • Generics can reduce code complexity

Dart’s built-in datatype List is a generic datatype, and you can plug any datatype you want into the List: integer, string, Boolean, etc

More information about Dart generics can be found here.

Dart Libraries

Dart currently has a number of libraries available to developers, and many of the functionality is not required for developers to implement themselves. You can import a package using an import statement, such as this:

import 'dart:html';
Copy the code

If you want to import one of your own code files, use the relative path. For example, there is a demo.dart file, and there is a util. Dart file in the same directory as this file.

Int add(int a, int b) {return a + b;
}
Copy the code

Dart to reference the util. Dart file in demo.dart, import it as follows:

// demo.dart

import './util.dart';

main() {
  print(add(1, 2));
}
Copy the code

You can use the as keyword to set a prefix, or alias, for a package to be imported, as in this 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();
Copy the code

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

// Import only foo import'package:lib1/lib1.dart'show foo; // Import all other parts except foo import'package:lib2/lib2.dart' hide foo;
Copy the code

Deferred as allows packages to be loaded lazily. Lazy packages are loaded only when the package is used, not when it is loaded initially, as in the following code:

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

asynchronous

Dart provides asynchronous operations such as async await in ES7, which are often encountered in Flutter development, such as network or other IO operations, file selection, etc., which require knowledge of asynchron. Async and await often come in pairs. If a method has time-consuming operations in it, you need to set the method to async and add await keyword to the operation. If the method has a return value, you need to shove the return value into the Future and return it, as shown in this code:

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

The following code uses Dart to fetch 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);
  });
}
Copy the code

Check out this article to learn more about Dart asynchronous operations.

conclusion

This blog is a long one, but it is mainly a translation (mostly) of the official document. If you have no difficulty reading English, you are advised to check out the official Document directly. Hope you all enjoy learning the Dart and Flutter.

reference

  • Dart Official Documentation
  • Dart asynchronous operations in-depth understanding

My open source project

  1. Google Flutter based on the open source Chinese client, hope you give a Star support, source code:
  • GitHub
  • Yards cloud

  1. Tetris based on the Flutter small game, I hope you give a Star support, source:
  • GitHub
  • Yards cloud

In the previous The next article
Write an open Source Chinese Client based on Flutter from 0 (1)

— Introduction to Flutter and building the development environment
Write an open Source Chinese Client based on Flutter from 0 (3)

— Introduction to Flutter & Common Widgets