This series documents the learning path of Flutter from scratch, starting with Dart grammar. This article removes most of the barriers to reading a Flutter tutorial and writing Flutter code that are language related. Worth collecting ~

Declare and initialize variables

int i = 1; // Non-null types must be initialized
int? k = 2; // Nullable type
int? h; // Declare only uninitialized, default to null
var j = 2; // Automatic inference type is int
late int m; // lazy loading
final name = 'taylor'; // Unchangeable
final String name = 'taylor'; // Unchangeable
Copy the code

Dart statements end with a semicolon; .

You can optionally assign an initial value to a variable when declaring it in Dart. But non-null types must be initialized.

Dart declares variables to display specified types. The types can be nullable or non-nullable. Said. Variables can also be declared using var, in which case the compiler automatically inferences the type of the variable based on its initial value.

The late keyword is used to indicate lazy loading, which makes lazy assignment of non-null types possible. It must be assigned before it is used, otherwise a runtime error will be reported.

Lazy loading is used to delay computationally time-consuming operations such as:

late String str = readFile();
Copy the code

The value of STR is not computed until it is first used.

?? Default values can be provided for null types

String? name;
var ret = name ?? ' '
Copy the code

Return an empty string if name is empty, name itself otherwise.

The number of

Int and double are two built-in numeric types in Dart, both of which are subtypes of num.

If the variable is num, it can be assigned both int and double

num i = 1;
i = 2.5;
Copy the code

string

“And “” can both define a string

var str1 = 'this is a str';
var str2 = "this is another str";
Copy the code

String concatenation

Use + to concatenate strings

var str = 'abc'+'def'; / / output abcdef
Copy the code

Multi-line string

Declare multiline strings using ”

var str = ''' this is a multiple line string ''';
Copy the code

Pure string

Use r to declare a pure string in which no escape occurs.

var str = r'this is a raw \n string'; // Output this is a raw \n string
Copy the code

The string contains an expression

A string can be nested with ${} to wrap an expression with a return value.

var str = 'today is ${data.get()}';
Copy the code

String and quantity convert to each other:

int.parse('1'); // Convert the string to int
double.parse('1.1'); // Convert the string to double
1.toString(); // Convert int to string
1.123.toStringAsFixed(2); // Convert double to string, output '1.12'
Copy the code

A collection of

The statement List

The counterpart of an ordered List is a List.

Use [] to declare an ordered list, and split the list elements. The last list element can still be followed by another, to eliminate copy and paste errors.

var list = [1.2.3,];
Copy the code

Accessing List elements

Lists are linear structures based on indexes that start at 0. Use [index] to get the list element of the specified index:

var first = list[0]; // Get the first element of the list
list[0] = 1; // Assign to the first element of the list
Copy the code

Expansion operator

. The expand operator is used to expand all elements of a list:

var list1 = [1.2.3];
var list2 = [...list1, 4.5.6];
Copy the code

The above code expands list1 when declaring list2, which contains [1,2,3,4,5,6]

In addition, there is a nullable expansion operator… ? , for filtering null lists:

var list; // If no initial value is assigned, the default value is null
var list2 = [1. ? list];// List2 is still [1]
Copy the code

Conditions for insert

If and for are two conditional expressions used to conditionally insert content into a list:

var list = [
    'aa'.'bb'.if (hasMore) 'cc'
];
Copy the code

List contains ‘cc’ if hasMore is true, otherwise it does not.

var list = [1.2.3];
var list2 = [
    '0'.for (var i in list) '$i'
];List2 contains 0,1,2,3
Copy the code

When you build list2, you add elements by iterating through the list.

Set

The elements in a Set are non-repeatable.

Declare Set with {} and split elements with:

var set = {1.2.3}; // Declare a set and assign the initial element
var set2 = <Int>{}; // Declare an empty set
var set3 = new Set(a);// Declare an empty set
var set4 = Set(a);// Declare an empty set. The new keyword is optional
Copy the code

Map

A Map is a key-value pair, where keys can be of any type but cannot be repeated.

var map = {
    'a': 1.'b': 2};// Declare and initialize a map, automatically infer type map 
      ,int>

var map2 = Map<String,Int>(); // Declare an empty map
map2['a'] = 1; / / write a map
var value = map['a']; / / read the map
Copy the code

[] is used to read and write maps.

const

Const is a keyword that cannot be modified once assigned:

// list
var list = const [1.2.3];
list.add(4); // Run an error, const list cannot add elements

// set
var set = const {1.2.3};
set.add(4); // Run an error, const set cannot add elements

// map
var map = const {'a': 1};
map['b'] = 2; // An error is reported, const map cannot add elements.
Copy the code

class

Class declarations

class Pointer {
    double x;
    double y;
    
    voidfunc() {... }// void indicates that no value is returned
    double getX(){
        returnx; }}Copy the code
  • Use keywordsclassDeclare a class.
  • Used in the class bodyType variable name;To declare a class member variable.
  • Used in the class bodyReturn value Method name (){method body}To declare class instance methods.

A constructor

The above code will report an error in x and y saying that non-empty fields must be initialized. Member variables are usually initialized in constructors.

A constructor is a special method that returns an instance of a class with the same signature and class name.

class Point {
    double x = 0;
    double y = 0;
    // A constructor with two arguments
    Point(double x, double y) {
        this.x = x;
        this.y = y; }}Copy the code

The constructor for assigning a value directly to a member variable has a succinct expression:

class Point {
    double x = 0;
    double y = 0;
    
    Point(this.x, this.y); // When a method has no method body, use it; End of the said
}
Copy the code

Named constructor

There’s another constructor in Dart that doesn’t have to have the same name as the class:

class Point {
  double x;
  double y;

  Point.fromMap(Map map)
      : x = map['x'],
        y = map['y'];
}
Copy the code

Declare a constructor for Point called fromMap, where: represents the initializer list used to initialize member variables, separated by, for each initialization assignment statement.

The initialization list is called in the highest order, and is initialized in the following order when a class is instantiated:

  1. Initialization list
  2. Parent class constructor
  3. Subclass constructor

Point.frommap () takes values from a Map instance and initializes them to member variables.

You can then use the named constructor like this:

Map map = {'x': 1.0.'y': 2.0};
Point point = Point.fromMap(map);
Copy the code

Named constructors have the advantage of hiding the complex logic of member assignment inside a class.

Inheritance constructor

The constructor of a subclass cannot exist independently, but must call the constructor of its parent class:

class SubPoint extends Point {
  SubPoint(double x, double y) {}
}
Copy the code

The SubPointer declaration will return an error and prompt the parent constructor to be called.

class SubPoint extends Point {
  SubPoint(double x, double y) : super(x, y);
}
Copy the code

The constructor of the parent class is called through super in the initializer list. The call to the superclass named constructor is similar:

class SubPoint extends Point {
  SubPoint(Map map) : super.fromMap(map);
}
Copy the code

Constructor redirection

Some constructors simply call another constructor, which can be done with this in the initializer:

class Point {
    double x = 0;
    double y = 0;
    
    Point(this.x, this.y);
    Point.onlyX(double x): this(x, 0);
}
Copy the code

Point.onlyx () is initialized by calling another constructor and assigning the y value to 0.

methods

Dart methods are also a type, corresponding to the Function class, so methods can be assigned to variables or passed as arguments to another method.

The two methods declared below are equivalent.
bool isValid(int value){
    returnvalue ! =0;
}

isValid(int value){// It is automatically inferred that the return type is bool
    returnvalue ! =0;
}
Copy the code

Declares a method that returns a Boolean value, taking an int as an argument.

The method return value bool is optional.

bool isValid(intvalue) => value ! =0;
Copy the code

If the method body has only one line of expression, it can be written as a single-line method style, with the method name and the method body connected by =>.

Methods in Dart do not have to belong to a class; they can also appear as top-level methods (defined in a.dart file). Methods defined in a class do not have the visibility modifier public private protected. Instead, they are simply delimited. functions and variables starting with _ are private, otherwise they are public.

Optional parameter & named parameter

Dart methods can have arguments with arbitrary data. Non-essential arguments can be declared as optional, so that no arguments are passed to them when the method is called:

bool isValid(int value1, [int value2 = 2.int value3 = 3]) {... }Copy the code

Defines a method that takes two optional arguments, the second and third of which are wrapped in [] to indicate that they are optional. It also provides default values for optional parameters when declaring methods to be used when no corresponding arguments are provided. So the following calls to this method are legal.

var ret = isValid(1) // Do not pass any optional arguments
var ret2 = isValid(1.2) // Pass an optional argument
var ret3 = isValid(1.2.3) // Pass in two optional arguments
Copy the code

If you want to pass only value1 and value3, you cannot use [] to define optional parameters. Hence {} :

bool isValid(int value1, {int value2 = 2.int value3 = 3{...}) }Copy the code

Then you can skip value2 and pass it directly to value3:

var ret = isValid(1, value3 : 3)
Copy the code

This syntax is called optional named parameters.

Dart also provides the keyword required to specify which of the many optional named parameters are required:

bool isValid(int value1, {int value2, required intvalue3}) {... }Copy the code

Anonymous methods

An anonymous method represents an operation on a given parameter. It is defined in the following syntax:

(type parameter) {method body};Copy the code

Anonymous functions can be represented as a single line if the method body has only one line of code:

(type parameter) => method body;Copy the code

The operator

Ternary operator

The ternary operator has the following format: Boolean? Expression 1: expression 2;

var ret = isValid ? 'good' : 'no-good';
Copy the code

Return expression 1 if isValid is true, and expression 2 otherwise.

The waterfall operator

The operator.. Used to merge multiple consecutive operations on the same object:

val paint = Paint() .. color = Colors.black .. strokeCap = StrokeCap.round .. strokeWidth =5.0
Copy the code

Builds a brush object and sets three properties in succession.

If the object is controllable, use? . :

paint? . color = Colors.black .. strokeCap = StrokeCap.round .. strokeWidth =5.0
Copy the code

Type determination operator

As is the strongcast operator, which represents a strongcast from one type to another.

Is is the type determination operator used to determine whether an instance is of a specified type.

is! Is the opposite of is.

Process control

if-else

if (isRaining()) {
  you.bringRainCoat();
} else if (isSnowing()) {
  you.wearJacket();
} else {
  car.putTopDown();
}
Copy the code

for

for (var i = 0; i < 5; i++) {
  message.write('! ');
}
Copy the code

If you don’t need to worry about the index value of the loop, you can do this:

for (var item in list) {
  item.do(a); }Copy the code

while

while(! isDone()) { doSomething(); }Copy the code
do {
  printLine();
} while(! atEndOfPage());Copy the code

break & continue

Break & continue can be used for for and while loops.

Break is used to break out of the loop

var i = 0
while (true) {
  if (i > 2) break;
  print('$i');
  i++;
} / / output is 0
Copy the code

Continue is used to skip the rest of the code for the current loop:

for (int i = 0; i < 10; i++) {
  if (i % 2= =0) continue;
  print('$i');
}/ / output 1,3,5,7,9
Copy the code

switch-case

Dart switch-case supports String, int, and enumeration comparisons. The following uses String as an example:

var command = 'OPEN';
switch (command) {
  case 'CLOSED': 
  case 'PENDING': // Both cases share logic
    executePending();
    break; // There must be a break
  case 'APPROVED':
    executeApproved();
    break;
  case 'DENIED':
    executeDenied();
    break;
  case 'OPEN':
    executeOpen();
    break;
  default: // Execute the default logic when all cases are missed
    executeUnknown();
}
Copy the code

keywords

All the keywords are shown below:

abstract 2 else import 2 show 1
as 2 enum in static 2
assert export 2 interface 2 super
async 1 extends is switch
await 3 extension 2 late 2 sync 1
break external 2 library 2 this
case factory 2 mixin 2 throw
catch false new true
class final null try
const finally on 1 typedef 2
continue for operator 2 var
covariant 2 Function 2 part 2 void
default get 2 required 2 while
deferred 2 hide 1 rethrow with
do if return yield 3
dynamic 2 implements 2 set 2

reference

Language tour | Dart