The subject catalog of Flutter: this catalog helps you quickly find out what you want to learn!!
This post continues with the Flutter- From Introduction to Project 04:Dart Grammar Quick Mastery (part 1) Analysis. As you can see from the previous post, people don’t like reading grammar related articles. But no matter I still continue to write: after all, if you want to do a good job, you must first sharpen its tools
All landowners function
Dart is an object-oriented language, so even though functions are objects, there is a type Function. This means that functions can be assigned to variables or passed as arguments to other functions. You can also call an instance of the Dart class as if it were a function. For more information, see: Callable -classes
// Function type tests
// Void represents the return value type
FuncFunc represents the name of the function
/ / () parameters
void funcFunc(){
}
// Omitted: no type is declared
funcFunc1(){
}
// For methods that contain only one expression, you can use a shorthand syntax:
funcFunc2() => print("=> "; Syntax is short for {return expression}");
Copy the code
Note: only one expression can be used at the arrow (=>) and semicolon (;). Statements cannot be used in this way. For example, you can’t put an if statement between these two symbols, but a ternary operator (? π yes.
-
A function can have two types of arguments: required and optional. All necessary parameters should be listed before the optional parameters. Optional parameters can be added after the required parameters have been listed.
-
An optional parameter can be an optional positional parameter or an optional named parameter, but cannot be both.
-
Default values can be defined for either of these optional parameters. But the default value must be a compile-time constant, such as a literal. If no default value is provided for this parameter, the default value for this parameter will be null.
/// Use bold and hidden as the values of your declared parameters
funcFunc3({bool bold, bool hidden}) {
print('$bold.$hidden'); // true,null
}
/ / call
funcFunc3(bold: true);
/// Use bold and hidden as your declared parameters, and the default values are false and True, respectively
funcFunc4({bool bold = false.bool hidden = true{})print('$bold.$hidden'); // false,true
}
// The default values are optional
funcFunc4();
// Optional positional arguments, marked as optional positional arguments with [] :
String funcFunc5(String person , String word, [String device]) {
var result = "$person say : $word";
if(device ! =null){
result = "$person say : $device";
}
print(result);
return result;
}
// Call the function
funcFunc5("KC"."Study in harmony, without haste or impatience."); KC say: Study in harmony, not in haste or impatience
funcFunc5("KC"."Study in harmony, without haste or impatience."."It's better to chase the wind than wait for it."); KC say: It's better to chase after the wind than wait for it
Copy the code
- Function as a class object -> pass a function as an argument to another function.
Functional programming ideas
// Functional programming ideas
funcFunc6(int num) = >print(num);
funcFunc7(){
var list = [1.2.3.4];
list.forEach(funcFunc6);
/**
flutter: 1
flutter: 2
flutter: 3
flutter: 4
* /
}
Copy the code
- Anonymous functions
Most functions can be named anonymously, such as main() or printElement(). You can also create an anonymous function called an anonymous function, and sometimes a lambda or a closure. You can assign an anonymous function to a variable, for example, you can add or remove it from a collection.
An anonymous function looks like a named function with arguments of -0 or more, separated by commas and optional type annotations between parentheses.
The following code block contains the body of the function:
([[Type] param1 [,...]. ]) { codeBlock; };Copy the code
The following example defines an anonymous function item with untyped arguments that is called by each item ‘in the list and outputs a string containing the value at the specified index.
var list = ['apples'.'bananas'.'oranges'];
list.forEach((item) {
print('${list.indexOf(item)}: $item');
});
Copy the code
Today operator
introduce | symbol |
---|---|
Unary suffix | expr++ expr– () [] . |
Unary prefix | -expr ! expr ~expr ++expr –expr |
Multiplication type | * / % ~ / |
Addition type | + – |
An operator | << >> |
Bitwise and | & |
The bitwise exclusive or | ^ |
Bitwise or | | |
Compare and type test | >= <= > < as is is! |
equivalent | = =! = |
Logic and | && |
Logic or | || |
Conditional operator | expr1 ? expr2 : expr3 |
Cascade operator | . |
The assignment | = * = / = = ~ / = % = + = – = < < = > > = & = ^ = | = |
Whether theseThe operator
orArithmetic operator
,Equivalence and relational operators
,Type test operator
γAssignment operator
γLogical operator
γ Bit operations and shift operators
Just like any other language! So just take a peek
Cascade:.
Allows you to perform multiple operations on members of a single object, specifically visibleclass
β¨ Control flow statement
- The if and the else
- The for loop
- While and do-while loops
- Break and continue
- The switch and the case
- assert
You can also change the flow of control by using try-catch and throw, see the exceptions section for details.
The grammar here is pretty much the same as we do for iOS development, so if you want to be more proficient, you can learn The Flutter
π Exception Statement
void excFunc(){
try {
print("KCFlutter");
} on Exception catch (e) {
// Any exception
print('Comes the exception:$e');
} catch (e) {
// Non-specific type
print('Non-specific types:$e'); }}Copy the code
Throw + catch + finally
11 the generic
If you look in the API documentation for the basic array type or List type, you’ll see that the type is actually List
, where <… The > tag indicates that the table is a generic type (or parameterized structure) — a type that contains parameters of a normal type. By convention, type variables are usually single-character names, such as E,T,S,K, and V.
- For example, if you’re going to use a string only
List
You can declare it asList<String>
In this way, your fellow programmers, as well as your tools (such as the Dart editor and the Dart VIRTUAL machine in debug mode), can detect the assignment of a non-string variable toList
Is probably wrong, here’s an example:
/ / generics
void genericsFunc(){
var names = List<String> (); names.addAll(['Hank'.'Cooci'.'CC']);
// names.add(100); // An error will be reported, because the generics determine the type of the contents of the list
}
Copy the code
- Another reason to use generics is
To reduce code duplication
.Generics allow you to share an interface and implementation for multiple typesIt still has advantages in debug mode and error warning for static analysis. For example, when you create an interface to cache an object:
// Generics allow you to share an interface and implementation for multiple types,
// It still has advantages in debug mode and error warning for static analysis
abstract class KCObjectCache{
Object getByKey(String key);
setByKey(String key,Object value);
}
// You find that you want a string specific interface, so you create another one:
abstract class KCStringCache{
String getByKey(String key);
setByKey(String key,String value);
}
// Next, you decide that you want a digital-only interface for this interface... You came up with this idea.
// Generic types make it easier for you to create these interfaces. Instead, you simply create an interface with a type parameter:
// Generics are the next big thing
abstract class Cache<T>{
// In this code, T is an alternate type, a placeholder, which you can treat as a subsequent type defined by the developer.
T getByKey(String key);
setByKey(String key,T value);
}
Copy the code
12 class
This content is also the most important! At ordinary times everyone development is also a must, I hope you have a good experience ~~βΊοΈ
12.1 object
Dart
Is an object oriented language and supports a language based onmixin
Inheritance method.Dart
All objects in the language are instances of a class, and all classes have the same base classObject
.- Based on the
mixin
A class can inherit from multiple parent classes.
// Class related tests
class LGPerson {
int age;
String name;
String hobby;
double height;
}
void classFunc(){
// The instance variable creates the test
var person = LGPerson();
person.age = 18;
person.name = "Cooci";
person.height = 182.0;
person.hobby = "iOS";
print(person.runtimeType); // LGPerson
}
Copy the code
-
Use.(dot) to call an instance variable or method.
-
Use? To ensure that the previous operand is not null, often used instead of., to avoid throwing an exception if the left operand is null.
-
Get the type of the object at run using the runtimeType method. This method will return Type ‘
12.2 Instance Variables
-
In the class definition, all uninitialized variables are initialized to null.
-
Dart implicitly defines setter methods for all variables in the class definition, and adds getters for non-empty variables.
var person2 = LGPerson();
person2.hobby = "Flutter"; // Use the setter method for hobby.
print(person2.hobby); // Use the getter method for hobby.
print("age = ${person2.age}, name = ${person2.name}"); //age = null, name = null
Copy the code
12.3 Constructors
To declare a constructor, simply create a method with the same name as the class (or add an extra identifier to name the constructor’s description). The most common form of a constructor is an automatically generated constructor that creates a new instance of a class:
class LGStudent {
int age;
String name;
String hobby;
double height;
// LGStudent(int age, String name, String hobby){
// // height has no constructed assignment
// this.age = age;
// this.name = name;
// this.hobby = hobby;
// }
// The this keyword points to the instance of the current class. The above code can be simplified as:
LGStudent(this.age,this.name,this.hobby);
}
// The constructor
var student1 = LGStudent(18."KC"."Constructor");
print("age = ${student1.age}, name = ${student1.name}"); // age = 18, name = KC
Copy the code
-
If you do not declare a constructor, the system provides a default constructor. The default constructor takes no arguments and calls the parent class’s parameterless constructor. : LGStudent ()
-
A child class does not inherit the constructor of its parent class. Subclasses have only the default constructor. (No arguments, no named constructor).
-
Using named constructors allows you to declare multiple constructors for a class, or to provide additional declarations:
// Name the constructor
LGStudent.fromMap(Map stuMap){
age = stuMap['age'];
name = stuMap['name'];
hobby = stuMap['hobby'];
height = stuMap['height'];
}
// Initialize the list
LGStudent.fromMaplist(Map stuMap):
age = stuMap['age'],
name = stuMap['name'],
hobby = stuMap['hobby'],
height = stuMap['height'] {// age = 18, name = cool C, hobby = 1, height = 180.0
print("age = $age, name = $name, hobby = $hobby, height = $height");
}
var stuMap = {'age': 18.'name': 'cool C'.'hobby': "Master Bottom".'height': 180.0};var student2 = LGStudent.fromMap(stuMap);
print("age = ${student2.age}, name = ${student2.name}"); // Age = 18, name = cool C
Copy the code
Redirect the constructor
Sometimes the purpose of a constructor is simply to redirect to another constructor in the same class. If the body of a redirected constructor is empty, then the constructor is called directly after the colon.
// The this keyword points to the instance of the current class. The above code can be simplified as:
LGStudent(this.age,this.name,this.hobby);
// Redirect the constructor
LGStudent.rediconstructor(int age, String name, String hobby) : this(age,
Crying "C", hobby); // : this is followed by a call to the above constructor
var student4 = LGStudent.rediconstructor(20."KC".'185.');
print("age = ${student4.age}, name = ${student4.name}, hobby = ${student4 .hobby}"); // age = 20, name = cry C, hobby = 185.
Copy the code
Static constructor
If your class produces objects that never change, you can make those objects compile-time constants. To do this, you need to define a const constructor and ensure that all instance variables are final.
// Static constructor
class LGTeacher{
final num age;
final String name;
const LGTeacher(this.age, this.name);
static final LGTeacher teacher = LGTeacher(300."No rush, no rush.");
}
// Static constructor
var teacher1 = LGTeacher(100."Harmonious Learning");
// teacher1.age = 200; // Error: The setter 'age' isn't defined for The class 'LGTeacher' cannot be modified
teacher1 = LGTeacher(200."Harmonious Learning");
print("age = ${teacher1.age}, name = ${teacher1.name}"); // Age = 200, name = 1
var teacher2 = LGTeacher.teacher;
Teacher2 = LGTeacher(200, "teacher2 "); // Age = 200, name = 1
print("age = ${teacher2.age}, name = ${teacher2.name}"); // Age = 300, name = no hurry
Copy the code
Factory constructor
When you implement a constructor decorated with the Factory keyword, the constructor does not have to create a new instance of the class. For example, the factory constructor might return instances from the cache, or it might return instances of subtypes. The following example demonstrates an object returned from the cache by a factory constructor:
// The factory constructor
class LGCar{
String name;
// The normal constructor
LGCar.func(this.name);
static final Map<String, LGCar> _cache = <String, LGCar>{};
factory LGCar(String name){
if (_cache.containsKey(name)){
return _cache[name];
}else{
final car = LGCar.func(name);
_cache[name] = car;
returncar; }}}// The factory constructor
var car = new LGCar("Ferrari");
print("name = ${car.name}"); // Name = Ferrari
Copy the code
12.4 methods
Instance methods: Instance methods of an object can access instance variables and this
Setters and Getters
Is a special method that provides reading and writing to method attributes. Each instance variable has an implicit getter method and maybe a setter if appropriate. You can create additional properties by implementing getters and setters, using the get and set keywords directly:
class LGRectangle {
num left;
num top;
num width;
num height;
LGRectangle(this.left, this.top, this.width, this.height);
// Define two computed properties: right and bottom.
num get right => left + width;
set right(num value) => left = value - width;
num get bottom => top + height;
set bottom(num value) => top = value - height;
}
// Test the method
void methodFunc(){
var rectangle = LGRectangle(10.20.100.300);
print('right = ${rectangle.right}, bottom = ${rectangle.bottom}');// right = 110, bottom = 320
}
Copy the code
Abstract methods
The Instance, getter, and setter methods can be abstract, that is, defining an interface but leaving the implementation to another class. To create an abstract method, use the semicolon (;) Substitute method body:
// Abstract method
abstract class LGDoer {
/ /... Define instance variables and methods...
void doSomething(); // Define an abstract method.
}
class LGEffectiveDoer extends LGDoer {
void doSomething() {
/ /... Provides an implementation, so the methods here are not abstract...
print("hello word"); }}Copy the code
12.5 Overloaded Operators
You can override the operators listed in the following table. For example, if you define a vector class, you can define a + method to add two vectors.
+ | | | [] |
---|---|---|
> / | ^ | [] = |
~ / | & | ~ |
> = | * | = = |
– | % | >> |
Here’s an example of a class that overrides the + and – operators:
// Overloaded operators
class Vector {
final int x;
final int y;
const Vector(this.x, this.y);
/// Overrides + (a + b).
Vector operator +(Vector v) {
return new Vector(x + v.x, y + v.y);
}
/// Overrides - (a - b).
Vector operator -(Vector v) {
return newVector(x - v.x, y - v.y); }}void vectorFunc() {
final v = new Vector(2.3);
final w = new Vector(2.2);
// v == (2, 3)
assert(v.x == 2 && v.y == 3);
// v + w == (4, 5)
assert((v + w).x == 4 && (v + w).y == 5);
// v - w == (0, 1)
assert((v - w).x == 0 && (v - w).y == 1);
}
Copy the code
If you override ==, you should also override the getter method for hashCode in the object. For the rewriting == and hashCode examples, see Implementing Map Keys.
For more information about overloading, see Extending a class.
12.6 Implicit Interface
Each class implicitly defines an interface that contains all instances of the class and all interfaces it implements. If you want to create A class A that supports the API of class B, but does not want to inherit from class B, then class A should implement the interface of class B.
A class implements one or more interfaces by declaring them with the Implements clause and then providing API interface requirements. Such as:
// Implicit interface
// A KCPerson containing the implicit interface for greet().
class KCPerson {
// In this interface, only the library is visible.
final _name;
// Not in the interface, because this is a constructor.
KCPerson(this._name);
// In this interface.
String greet(who) => 'Hello, $who. I am $_name. ';
}
An implementation of the KCPerson interface.
class KCImposter implements KCPerson {
// We have to define it, but we don't use it.
final _name = "";
String greet(who) => 'Hi $who. Do you know who I am? ';
}
greetBob(KCPerson person) => person.greet('bob');
imposterFunc() {
print(greetBob(new KCPerson('KC')));
print(greetBob(new KCImposter()));
}
Copy the code
Extending a class
Use extends to create a subclass, and supper will point to the superclass:
class Television {
void turnOn() {
_illuminateDisplay();
_activateIrSensor();
}
// ...
}
class SmartTelevision extends Television {
void turnOn() {
super.turnOn();
_bootNetworkInterface();
_initializeMemory();
_upgradeApps();
}
// ...
}
Copy the code
Subclasses can override instance methods, getters, and setters. Here’s an example of overriding the Object class method noSuchMethod(), which is called when code attempts to use a nonexistent method or instance variable.
class A {
// If you do not override noSuchMethod and use a non-existent member, NoSuchMethodError will result.
void noSuchMethod(Invocation mirror) {
print('You tried to use a non-existent member:' +
'${mirror.memberName}'); }}Copy the code
You can use the @override annotation to indicate that you have overridden a member.
class A {
@override
void noSuchMethod(Invocation mirror) {
// ...}}Copy the code
If you use noSuchMethod() to implement every possible getter, setter, and class method, then you can use the @proxy annotation to avoid warnings.
@proxy
class A {
void noSuchMethod(Invocation mirror) {
// ...}}Copy the code
For more information about annotations, refer to metadata.
12.7 Enumeration types
An enumeration type, commonly called enumerations or enums, is a special class used to represent a fixed number of constants.
To declare an enumeration type, use the keyword enum:
enum LGColor {
red,
green,
blue
}
Copy the code
Each value in the enumeration has an index getter method, which returns a position starting from 0 in the enumeration declaration. For example, the first value has an index value of 0 and the second value has an index value of 1.
assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);
Copy the code
To get all the values of the enumerated list, use the values constant of the enumeration.
List<Color> colors = Color.values;
assert(colors[2] == Color.blue);
Copy the code
You can use enumerations in switch statements. If e on switch (e) is an enumeration of explicit type, then a warning will pop up if you don’t handle all enumerated values:
// Enumeration test enum LGColor{blue, green, orange} // Each value in the enumeration has an index getter method, which returns a position starting from 0 in the enumeration declaration. For example, the first value has an index value of 0 and the second value has an index value of 1. void enumFunc(){ assert(LGColor.blue.index == 0); assert(LGColor.green.index == 1); assert(LGColor.orange.index == 2); List<LGColor> colors = LGColor.values; print(colors); // [LGColor.blue, LGColor.green, LGColor.orange] LGColor color1 = LGColor.blue; switch(color1) { case LGColor.blue: print("blue"); break; case LGColor.green: print("green"); break; default: print("orange"); }}Copy the code
Enumeration types have the following restrictions
- You cannot mix or implement an enumeration in a subclass.
- You cannot explicitly instantiate an enumeration.
For more information, see Dart Language Specification.
13 References
Flutter official documentation: https://flutterchina.club
The Dart official documentation: https://dart.dev/guides/language/language-tour
Geek college team: https://wiki.jikexueyuan.com/project/dart-language-tour/important-concepts.html
The Dart grammar learning: https://www.jianshu.com/p/9e5f4c81cc7d
The Dart syntax: https://www.pipipi.net/dart/dart-syntax.html
Here to recommend a very good iOS dry goods output point: logical iOS technology number. Build iOS prosperity ecology, start from your little love π