preface

Flutter is developed using Dart, an object-oriented programming language introduced by Google in 2011. Dart is currently available in version 2.4.0.

To do a good job, he must sharpen his tools.

To better develop Flutter applications, familiarize yourself with the basic syntax of Dart

Hello, world!

When you learn any programming language, you basically output Hello, world!

The editor used in this document is Android Studio(because I do Android development) for development

New dart_demo dart files, the dart program began, main () function code is as follows:

void main() {print('Hello, world! ');
}
Copy the code

After editing, click on the Run menu in the right-click menu to Run the Dart file

The data type

Everything in Dart is an Object, including numbers, functions, etc. They all inherit from Object, and the default value is NULL (including numbers) so numbers, strings can call various methods

The following built-in types are supported in Dart:

  • String
  • Number
  • Boolean
  • List
  • Set
  • Map
  • Rune
  • Symbol

The Drat language is essentially a dynamically typed language. Types are optional, and variables can be declared using var or types

1. String

The Dart string is a sequence of UTF-16 units. String assignments can use either single or double quotation marks

var str1 = "MuFeng";
String str2 = 'MuFeng';
Copy the code

If double quotes are used, single quotes can be enclosed, if single quotes are used, double quotes can be enclosed, otherwise “\” needs to be escaped

var str1 = "My name is 'MuFeng'";
var str2 = 'My name is "MuFeng"';
var str3 = "My name is \"MuFeng\"";
Copy the code

Multiple string assignments can be made using three single quotes or three double quotes

var str5 = ' ''MuFeng Study
Dart for Flutter!
'' ';
var str6 = """MuFeng Study
Dart for Flutter!
""";
Copy the code

In Dart, adjacent strings are automatically concatenated at compile time. One problem is that if multiple strings are adjacent, the middle string cannot be empty or an error will be reported, but if single and double quotes are adjacent, even null values will not be reported

var name = 'Mu'' ''Feng'; Var name1 ='Mu'""'Feng'; // No error will be reportedCopy the code

Assert is a language-built assert function that is valid only in check mode and terminates immediately if an assertion fails

assert(name == "MuFeng");
Copy the code

There are three ways to concatenate strings in Dart:

  1. Adopt “+” splicing
  2. Use “adjacent string autoconcatenation” as described above.
  3. Adopt”{}” inserts the expression
var name = "MuFeng";
print("My name is $name");
Copy the code

Declare the original string by prefixing the string with the character “r” to avoid escaping “\”, which is useful in regular expressions

print(r"Newline: \n");
Copy the code

2. Number

There are two types of numbers in Dart:

Int Integer values are not greater than 64 bits, depending on the platform. On the Dart VM, the values range from -263 to 263-1. When Dart is compiled into JavaScript, the values range from -253 to 253-1

Double A 64-bit double precision floating point number

String to number conversion method:

//String->int
var a = int.parse('1); //String->double var a = double. Parse (1.1); //int->String var a = 1.toString(); Var a = 1.23456. ToStringAsFixed (2)//==1.23 var h = 59506490075; Print (" $h -> 0x${h.toradixString (16).toupperCase ()}");Copy the code

3. Boolean

Dart uses type bool to represent a Boolean value.

var isShow = true;
bool isHide = false;
Copy the code

4. List

Lists, also called arrays, are common methods for adding, indexing, deleting, and so on

Var List = List(); var List = List(); var list1 = List(10); Var list2 = [var list2 = ['a'.'b'1]; // Add element list.add(2); // Add multiple elements list.addall (list2); // Get the length of Listprint(list.length); // Get the element using the indexprint(list[0]); // Find the index number of an elementprint(list.indexOf('b')); Var index = list.indexof (1); list.removeAt(index);print(list); // Delete all elements list.clear();print(list.length);
Copy the code

Sort () is used to sort the elements of the List and we must specify a function to compare the two objects, where return < 0 means less than, =0 means the same, and >0 means greater than

var list3 = ['c'.'a'.'r'.'y'];
  list3.sort((a,b)=>a.compareTo(b));
  print(list3);
Copy the code

List and other containers can specify parameter types

var list = List<String>();
list.add("a"); list.add(5); // The parameter type must be consistentCopy the code

5. Set

The collection is unordered in Dart and each element is unique because it is unordered and therefore cannot be accessed by index like a List

void main(){
  var set = Set();

  set.addAll(['name'.'sex'.'age']);
  print(set.length); // Add an existing element invalid set.add("name");
  print(set.length); // Remove element set.remove("sex");
  print(set); // Check if Set contains an elementprint(set.contains("name")); // Check if there are multiple elements in the Setprint(set.containsAll(["name"."age"]));
  set.addAll(['name'.'sex'.'age']); // Get the intersection of two sets varset1 = Set.from(['name'.'MuFeng']);
  var set2 = set.intersection(set1);
  print("set2 = $set2");

}
Copy the code

6. Map

A Map, also known as a dictionary, is an unordered container of key-value pairs

void mainVar Map = {var Map = {"name": "MuFeng"."age": 25."la": ["Android".'Java'.'Kotlin'.'Flutter']}; var map1 = Map(); Var map2 = Map<String, Object>(); //Map assignment, parentheses are Key, this is not array Map ["sex"] = "Male"; // Unlike Set, if the second Key is present, the Value overwrites the previous data Map ["age"] = 30;
  print(map); // Retrieves whether the Map contains a Keyprint(map.containsKey("age")); // Delete a key pair map.remove("sex");
  print(map);
}
Copy the code

You can use getKeys and getValues to get all keys or iterators for all Values

 var keys = map.keys;
  print(keys);

  var values = map.values;
  print(values); // There is a function in the iterator, any, which checks the data in the iterator when one of the elements runs the functionreturn true, then the return value of any istrue, or forfalse// The opposite is every, which requires all functions to runreturn true, then every returnstrue
  print(values.any((v) => v == 'MuFeng'));
  print(values.every((v) => v == 'MuFeng')); // It can be usedforForEach ((k,v){forEach(k,v){print("$k and $v"); }); // Retrieves whether a key or value is includedprint(map.containsKey("name"));
  print(map.containsValue("MuFeng"));

  //V putIfAbsent(K key, Function V ifAbsent()) Function {// If a key is Absent, start () {var map3 = {}; map3.putIfAbsent("name", () = >'MuFeng');
  print(map3);
Copy the code

function

1. Function definition

Functions are also objects and return null when no return value is specified

String sayHello(String name){
  return 'Hello, $name! ';
}
main(){
  assert(sayHello is Function, "Type error");
  print(sayHello("MuFeng"));
}
Copy the code

Note: The assert function assert(), in Debug mode, throws an exception when the value of an expression is false. In the new SDK, assert() adds a second argument, message, to output specific information when an exception is thrown

Since types are optional in Dart, you can also write this

sayHello(name){
    return "Hello, $name!";
}
Copy the code

However, it is recommended to specify the input type and return value type of the function, so that it is easy to modify, easy to read

If the function simply returns the value of an expression, use the arrow syntax “=>expr;” , which is equivalent to “{return expr; }”, so the above function can be modified as follows:

sayHello(name) => "Hello, $name!";
Copy the code

Dart “()=>expr;” Define anonymous functions:

var sayHello = (name) => "Hello, $name!";
Copy the code

2. Function alias

  • Normal function definition. Function signature information is lost after assignment
class Sort{
  Function compare;

  Sort(int f(Object a, Object b)){
    compare = f;
  }
}

int sort1(Object a, Object b) => 0;

main(){ Sort sort = Sort(sort1); assert(sort.compare is Function); // Missing function specific information, function signature information}Copy the code
  • Give the function an alias to make it easier to use
typedef int Compare(Object a, Object b);

class Sort{
  Compare compare;

  Sort(this.compare);
}

int sort(Object a, Object b) => 0;

main(){
  Sort s = Sort(sort);
  assert(s.compare is Function);
  assert(s.compare is Compare);
}
Copy the code

3. Optional parameters

Dart supports two optional parameters: name optional parameter and location optional parameter. However, the two optional parameters cannot be used simultaneously

  • The parameters outside the curly braces are mandatory. Zero or more parameters inside the curly braces can be specified, regardless of the sequence. Parameter names must be specified when the function is called
  • Positional optional arguments use brackets []. In positional optional arguments, zero or more arguments in brackets can be specified, and their values are assigned in sequence when called
FunA(a,{b,c=3,d=4,e}){
  print("$a $b $c $d $e");
}

FunB(a, [b,c=3,d=4,e]){
  print("$a $b $c $d $e");
}

main(){ FunA(1,b: 3,c: 5,d: 6,e: 100); ,22,33 FunB (2); }Copy the code

Operator and process control statements

1. The integer

/The division operator yields the result of type double.

To take the integer part divided by two numbers, use the integer operator
~ /

var a = 3;
var b = 2;
print(a~/b); // The output is 1print(a/b); // The output is 1.5Copy the code

2. The cascade

When you want to perform a series of operations on a single object, use the cascade operator **.. 六四屠杀

class Person{
  String name;
  String country;
  void setCountry(String country) => this.country = country;

  String toString() => "Name: $name\nCountry: $country";
}

void main(){ Person person = Person(); person .. name ="MuFeng"
  ..setCountry("China");
  print(person);
}
Copy the code

3. If statements

If statements are judged by bool, as in most languages

void main(){
  var i = 10;
  if(i < 0){
    print("Less than");
  }else if(i == 0){
    print("Zero");
  }else{
    print("Greater than zero"); }}Copy the code

Dart criteria must be Booleans, not other types

4. The cycle

for(int i = 0; i<3; i++){
    print(i);
}
Copy the code

If the iterator is a container, forEach or for-in can be used

Var c = [0]; c.forEach((x) =>print("forEach: $x"));

for(var x in c){
    print("for-in: $x");
}
Copy the code

5. The Switch and the Case

The switch argument can be num or String

If the clause is not empty, break must be added; otherwise, an exception will be raised

If you want to fail and the case statements are not empty and fail in order, you can use a continue and a label

void main() {
  var command = 'CLOSED';
  switch (command) {
    case 'CLOSED':
      print('CLOSED');
      continue nowClosed; // Continues executing at the nowClosed label.
    case 'OPEN':
      print('OPEN');
      break;
    nowClosed: // Runs for both CLOSED and NOW_CLOSED.
    case 'NOW_CLOSED':
      print('NOW_CLOSED');
      break; }}Copy the code

6. Exception handling

Dart can throw non-empty objects (not just exceptions and errors) as exceptions

throw ExpectException("Value must be greater than 0!");
throw "Value must be greater than 0!";
Copy the code

Classes and objects

Dart is an object-oriented language that uses classes and single integration. All objects are instances of classes, and all classes are subclasses of Object

Definition 1.

Class definitions use the class keyword. If you define a constructor for display, the default is a no-argument constructor. The new keyword is not required when creating objects

class Point{
    num x;
    num y;
    num z;
}

void main(){
    var point = Point();
    print(point.hashCode); // If the parent class is undefined, it inherits from Object} by default.Copy the code

2. Constructor

For simple argument passing, you can prefix the constructor argument with the this keyword or the argument with: reassignment

class Point{ num x; num y; num z; Point(this.x, this.y, z){// The first value is passed to this.x, the second value is passed to this.y this.z = z; } /// Name the constructor in the format class.name (var param) point.fromelist (var list): X = list[0], y = list[1], z = list[2]{// Use colon to initialize ratio there} String toString()=>'x: $x y: $y z: $z';
}

void mainVar p1 = new Point(1,2,3); Var p2 = Point. FromeList ((4 and 6));print(p1);
    print(p2);
}
Copy the code

If you want to create an immutable object, you can define a compile-time constant object that needs to be preceded by const

class Point{ final num x; final num y; const Point(this.x, this.y); Const static final Point Point = const Point(1,1); }Copy the code

3. The Getters and Setters

Get and set are methods used to read and write an object property. Each field has an implicit Getter and Setter, but is called obj.x instead of obj.x().

You can extend this functionality with the get and set keywords. If a field is final or const, it has only one getter

class Rectangle { num left; num top; num width; num 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;
}

void main(){rect = Rectangle(3,4,20,15); assert(rect.left == 3); rect.right = 12; assert(rect.left == -8); }Copy the code

4. An abstract class

In Dart classes and interfaces are unified, classes are interfaces and if you want to override some of the functionality, you can inherit a class and if you want to implement some of the functionality, you can implement a class

Use the abstract keyword to define an abstract class, and the abstract class cannot be instantiated. Abstract methods do not need the keyword, and simply end with sorting

// Define a Shape class/interface num perimeter(); } class Rectangle implements Shape{//Rectangle implements Shape; width; Rectangle(this.height, this.width); @override num perimeter() => 2*height + 2*width; } class Square extends Rectangle{ Square(num size): super(size,size); } voidmain(){
  var s = Square(20);
  print(s.perimeter());
}
Copy the code

5. Factory constructor

Factory alone, because it’s not just a constructor, it’s a pattern sometimes in order to return a cache object that’s already been created, the original paparazzi method is not enough so you can use Factory pattern to define the constructor and use the keyword new to get the cache object that’s already been created

class Logger{
  final String name;
  bool mute = false; Static final Map<String, Logger> _cache = <String,Logger>{}; factory Logger(String name){if(_cache.containsKey(name)){
      return _cache[name];
    }else{
      final logger = new Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }

  Logger._internal(this.name);
  void log(String msg){
    if(! mute){print(msg);
    }
  }
}

void main(){
  var logger = new Logger('UI'); logger.. log("Button clicker")
  ..log("EditText Edit");
}
Copy the code

Asynchronous support

Dart contains a number of functions that return Future or Stream objects. These functions return immediately after setting up time-consuming tasks (I/O operations) and do not wait for time-consuming tasks to complete. Asynchronous programming with async and await keywords.

1. Deal with the Future

You can obtain the result of a Future execution in two ways:

  • Use async and await
  • A Future API

Code that uses the async and await keywords is asynchronous. Although it looks a bit like synchronous code

await lookUpVersion();
Copy the code

To use await, the code must be in an asynchronous function (using async token functions) :

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

Tip: While a one-step function may perform time-consuming operations, it does not wait for them. In contrast, an asynchronous function executes only when it encounters the first await expression.

Use try, catch, and finally to handle errors caused by using await in code

try{
  version = await lookUpVersion();
}catch(e){
}
Copy the code

You can use await multiple times in an asynchronous function.

var entrypoint = await findEntrypoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);
Copy the code

In await expressions, the value of the expression is usually a Future object; Await expression execution results in the returned object. Await expression blocks execution of code until the desired object is returned

2. The Stream processing

When you need to get data values from a Stream, you can do so in one of two ways:

  • Use async and an async loop (await for)
  • Using Stream API

Tip: Before using await for, make sure your code is clear and you really want to wait for the results of all the streams. For example, UI event listeners should not normally use await for because the UI framework sends an endless stream of events

Here’s how an asynchronous for loop can be used:

await for(varOrType indentifier in expression){}
Copy the code

The value returned by the above expression must be of type Stream. The execution process is as follows:

  • Wait until the stream emits a value
  • Executes the body of the for loop, setting the variable to the emitted value
  • Repeat 1 and 2 until the flow is closed

Use a break or return statement to stop receiving data from the stream, thus breaking out of the for loop and unregistering the stream. If you encounter a compilation error while implementing an asynchronous for loop, check to ensure that await for is in an asynchronous function.

conclusion

This article provides an overview of the features commonly used in the Dart language. Getting familiar with Flutter is the first step, but then it needs to be applied to Flutter. Learning to receive while writing will be faster