当前位置:网站首页>First try dart, notes
First try dart, notes
2022-07-19 15:15:00 【Humanoid bug maker 9527】
Catalog
Declaration of variables
1. var
Be similar to JavaScript Medium var, It can accept any type of variable , But the biggest difference is Dart in var Once the variable is assigned , The type will be determined , You can't change the type , Such as :
var t = "hi world";
// The following code is in dart China will report an error , Because of the variable t The type of has been determined to be String,
// Once the type is determined, it cannot be changed .
t = 1000;
The above code is in JavaScript There is no problem , Front end developers need to pay attention to , The difference is because Dart It's a strongly typed language in itself , Any variable has a definite type , stay Dart in , When used var After declaring a variable ,Dart At compile time, we will infer the type of the first assigned data , After compilation, its type has been determined , and JavaScript Is a purely weakly typed scripting language ,var It's just the way variables are declared .
2. dynamic and Object
Object yes Dart The root base class of all objects , That is to say Dart All types in are Object Subclasses of ( Include Function and Null), So any kind of data can be assigned to Object Declared object . dynamic And Object Declared variables can be assigned to any object , And the type of assignment can be changed later , This sum var Is different , Such as :
dynamic t;
Object x;
t = "hi world";
x = 'Hello Object';
// There is no problem with the following code
t = 1000;
x = 1000;
dynamic And Object The difference is dynamic The declared object compiler provides all possible combinations , and Object Declared objects can only use Object Properties and methods of , Otherwise, the compiler will report an error , Such as :
dynamic a;
Object b = "";
main() {
a = "";
printLengths();
}
printLengths() {
// normal
print(a.length);
// Report errors The getter 'length' is not defined for the class 'Object'
print(b.length);
}
dynamic We need to pay more attention when using it , It's easy to introduce a runtime error , For example, the following code will not report an error when compiling , An error will be reported during operation :
print(a.xx); // a Is string , No, "xx" attribute , No errors will be reported at compile time , The runtime will report an error
3. final and const
If you never plan to change a variable , So use final or const, No var, It's not a type either . One final Variable can only be set once , The difference is :const Variable is a compile time constant ( Directly replace with constant value at compile time ),final Variables are initialized the first time they are used . By final perhaps const Decorated variable , Variable types can be omitted , Such as :
// It can be omitted String This type declaration
final str = "hi world";
//final String str = "hi world";
const str1 = "hi world";
//const String str1 = "hi world";
4. Air safety (null-safety)
Dart Everything in is the object , This means that if we define a number , If we use it before initializing it , If there is no inspection mechanism , You can't report a mistake , such as :
test() {
int i;
print(i*8);
}
stay Dart Before introducing empty security , The above code will not report an error before execution , But it will trigger a runtime error , as a result of i The value of is null . But now there is free safety , When defining variables, we can specify whether the variables are nullable or not .
int i = 8; // The default value is not null , Must be initialized at definition time .
int? j; // Defined as nullable type , For nullable variables , We must judge the space before using .
// If we expect that the variable cannot be empty , But its initial value cannot be determined when defining , I can add late keyword ,
// Indicates that it will be initialized later , But before using it formally, you must ensure that it has been initialized , Otherwise, an error will be reported
late int k;
k=9;
If a variable is defined as nullable , In some cases, even if we assign a value to it , But the preprocessor may still not recognize , At this time, we will explicitly ( By adding a ”!“ Symbol ) Tell the preprocessor that it is no longer null 了 , such as :
class Test{
int? i;
Function? fun;
say(){
if(i!=null) {
print(i! * 8); // Because the sentence has been empty , So I can walk here i It must not be null, If there is no explicit declaration , be IDE Will report a mistake
}
if(fun!=null){
fun!(); // ditto
}
}
}
If the function variable in the above can be null , You can use syntax sugar when calling :
fun?.call() // fun If it is not empty, it will be called
function
Dart Is a real object-oriented language , So even functions are objects , And there's a type Function. This means that functions can be assigned to variables or passed as arguments to other functions , This is a typical feature of functional programming .
1. Function declaration
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
Dart Function declaration if the return value type is not explicitly declared, it defaults to dynamic Handle , Be careful , Function return value has no type inference :
typedef bool CALLBACK();
// Do not specify return type , The default is dynamic, No bool
isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
void test(CALLBACK cb){
print(cb());
}
// Report errors ,isNoble No bool type
test(isNoble);
For functions that contain only one expression , You can use shorthand syntax :
bool isNoble (int atomicNumber)=> true ;
2. Function as variable
var say = (str){
print(str);
};
say("hi world");
#3. Function passed as parameter
void execute(var callback) {
callback();
}
execute(() => print("xxx"))
(1) Optional position parameters
Wrapping a set of function parameters , use [] Marked as an optional positional parameter , And put it at the end of the parameter list :
String say(String from, String msg, [String? device]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
return result;
}
Here's an example of calling this function without optional arguments :
say('Bob', 'Howdy'); // The result is : Bob says Howdy
Here is an example of calling this function with the third parameter :
say('Bob', 'Howdy', 'smoke signal'); // The result is :Bob says Howdy with a smoke signal
(2) Optional named parameters
When defining a function , Use {param1, param2, …}, At the end of the parameter list , Used to specify named parameters . for example :
// Set up [bold] and [hidden] sign
void enableFlags({
bool bold, bool hidden}) {
// ...
}
When you call a function , You can use the specified named parameter . for example :paramName: value
enableFlags(bold: true, hidden: false);
Optional named parameters in Flutter It's used a lot in . Be careful , You can't use optional positional parameters and optional named parameters at the same time .
mixin
Dart Multiple inheritance is not supported , But it supports mixin, simply mixin Sure “ Combine ” Multiple classes , Let's use an example to understand .
Define a Person class , Realize eating 、 speak 、 Walk and write code , At the same time define a Dog class , Realize eating 、 And walking function :
class Person {
say() {
print('say');
}
}
mixin Eat {
eat() {
print('eat');
}
}
mixin Walk {
walk() {
print('walk');
}
}
mixin Code {
code() {
print('key');
}
}
class Dog with Eat, Walk{
}
class Man extends Person with Eat, Walk, Code{
}
We defined several mixin, And then through with Keywords combine them into different classes . There is one caveat : If more than one mixin There is a method with the same name in ,with when , The last one will be used by default mixin Of ,mixin In the method, you can use super Before keyword call mixin Or methods in a class . We only introduce mixin The most basic feature , About mixin For more detailed content, readers can baidu by themselves .
Asynchronous Support
Dart Class libraries have a lot of returns Future perhaps Stream Object function . These functions are called asynchronous functions : They only return after setting up some time-consuming operations , Such as IO operation . Instead of waiting for the operation to complete .
async and await Keywords support asynchronous programming , Allows you to write asynchronous code much like synchronous code .
1. Future
Future And JavaScript Medium Promise Very similar , Represents the final completion of an asynchronous operation ( Or failure ) And the expression of its result value . Simply speaking , It's used to handle asynchronous operations , If the asynchronous processing is successful, the successful operation will be executed , If the asynchronous processing fails, catch the error or stop the subsequent operation . One Future Only one result , Or success , Or failure .
Because of its many functions , Here we only introduce its common API And characteristics . also , please remember ,Future All of the API The return value of is still a Future object , So it's very convenient to chain call .
(1)Future.then
For the convenience of the example , In this case we use Future.delayed Created a delayed task ( The actual scene would be a real time-consuming task , For example, a network request ), namely 2 The result string is returned in seconds "hi world!", And then we were in then Receive asynchronous results and print the results , The code is as follows :
Future.delayed(Duration(seconds: 2),(){
return "hi world!";
}).then((data){
print(data);
});
(2)Future.catchError
If an error occurs in an asynchronous task , We can do it in catchError Error caught in , Let's change the above example to :
Future.delayed(Duration(seconds: 2),(){
//return "hi world!";
throw AssertionError("Error");
}).then((data){
// Successful execution will come here
print("success");
}).catchError((e){
// Execution failure will come here
print(e);
});
In this example , We threw an exception in an asynchronous task ,then The callback function for will not be executed , In its place catchError The callback function will be called ; however , It's not just catchError Callback to catch errors ,then Method also has an optional parameter onError, We can also use it to catch exceptions :
Future.delayed(Duration(seconds: 2), () {
//return "hi world!";
throw AssertionError("Error");
}).then((data) {
print("success");
}, onError: (e) {
print(e);
});
(3)Future.whenComplete
Sometimes , We will come across a scenario where we need to do something no matter whether the asynchronous task is successful or failed , For example, the load dialog box pops up before the network request , Close the dialog at the end of the request . This scenario , There are two ways , The first is in the then or catch Close the dialog box in , The second is to use Future Of whenComplete Callback , Let's change the above example :
Future.delayed(Duration(seconds: 2),(){
//return "hi world!";
throw AssertionError("Error");
}).then((data){
// Successful execution will come here
print(data);
}).catchError((e){
// Execution failure will come here
print(e);
}).whenComplete((){
// Success or failure will come here
});
(4)Future.wait
Sometimes , We need to wait for multiple asynchronous tasks to be executed before doing some operations , For example, we have an interface , You need to get data from two network interfaces first , After success , We need to process the data of the two interfaces before displaying it to UI On the interface , What to do ? The answer is Future.wait, It accepts a Future Array parameters , Only all in the array Future After all of them are successfully executed , Will trigger then The successful callback of , As long as there is one Future Execution failure , An error callback is triggered . below , We simulate Future.delayed To simulate two asynchronous tasks of data acquisition , When both asynchronous tasks succeed , Print the results of two asynchronous tasks , The code is as follows :
Future.wait([
// 2 Seconds to return results
Future.delayed(Duration(seconds: 2), () {
return "hello";
}),
// 4 Seconds to return results
Future.delayed(Duration(seconds: 4), () {
return " world";
})
]).then((results){
print(results[0]+results[1]);
}).catchError((e){
print(e);
});
Execute the code above ,4 In seconds, you'll see in the console “hello world”.
2. async/await
Dart Medium async/await and JavaScript Medium async/await The function is the same : Asynchronous task serialization . If you already know JavaScript Medium async/await Usage of , You can skip this section .
(1) Back to hell (Callback Hell)
If there's a lot of asynchronous logic in the code , And when a large number of asynchronous tasks depend on the results of other asynchronous tasks , It's bound to happen Future.then Callback in the set of callbacks . for instance , For example, there is a requirement scenario where users log in first , After successful login, you will get the user ID, And then through the user ID, Then ask for the user's personal information , After obtaining the user's personal information , For ease of use , We need to cache it on the local file system , The code is as follows :
// First, define each asynchronous task separately
Future<String> login(String userName, String pwd){
...
// The user login
};
Future<String> getUserInfo(String id){
...
// Get user information
};
Future saveUserInfo(String userInfo){
...
// Save user information
};
Next , Perform the entire task flow :
login("alice","******").then((id){
// Log in successfully and pass ,id Get user information
getUserInfo(id).then((userInfo){
// Get user information and save
saveUserInfo(userInfo).then((){
// Save user information , Next, do something else
...
});
});
})
You can feel it , If there are a lot of asynchronous dependencies in the business logic , There will be the above situation that callback is nested in callback , Too much nesting will lead to a decrease in code readability and an increase in error rate , And it's very difficult to maintain , The question is figuratively called Back to hell (Callback Hell). Back to hell before JavaScript It's very prominent , It's also JavaScript Make complaints about the most points , But as the ECMAScript After the standard is released , This problem has been solved very well , And the two great artifact to solve hell is ECMAScript6 Introduced Promise, as well as ECMAScript7 Introduced in async/await. And in the Dart It's almost completely translational in JavaScript The two of them :Future amount to Promise, and async/await I didn't even change my name . Let's take a look at passing Future and async/await How to eliminate the nesting problem in the above example .
(2) Eliminate callback hell
There are two main ways to eliminate callback hell :
One 、 Use Future eliminate Callback Hell
login("alice","******").then((id){
return getUserInfo(id);
}).then((userInfo){
return saveUserInfo(userInfo);
}).then((e){
// Perform the next operation
}).catchError((e){
// Error handling
print(e);
});
As mentioned above , “Future All of the API The return value of is still a Future object , So it's very convenient to chain call ” , If in then It's a Future Words , The future Will execute , At the end of execution, the following then Callback , So down in turn , It avoids layers of nesting .
Two 、 Use async/await eliminate callback hell
adopt Future Call back and return Future Although it can avoid layer by layer nesting , But there is still a layer of callback , Is there a way to perform asynchronous tasks like writing synchronous code without using callbacks ? The answer is yes , This is about using async/await 了 , Let's take a look at the code first , And then explain , The code is as follows :
task() async {
try{
String id = await login("alice","******");
String userInfo = await getUserInfo(id);
await saveUserInfo(userInfo);
// Perform the next operation
} catch(e){
// Error handling
print(e);
}
}
async Used to indicate that a function is asynchronous , The defined function will return a Future object , have access to then Method to add a callback function .
await There's a Future, Indicates waiting for the asynchronous task to complete , Only after asynchronous completion can we go down ;await Must appear in async Internal function .
You can see , We go through async/await An asynchronous flow is represented by synchronous code .
Actually , Whether in the JavaScript still Dart in ,async/await It's just a grammar candy , The compiler or interpreter will eventually turn it into a Promise(Future) The call chain of .
Stream
Stream It is also used to receive asynchronous event data , and Future The difference is , It can receive the results of multiple asynchronous operations ( Success or failure ). in other words , When performing asynchronous tasks , You can pass result data or error exceptions by triggering success or failure events multiple times . Stream It is often used in asynchronous task scenarios that can read data multiple times , Such as Internet content download 、 Document reading and writing, etc . for instance :
Stream.fromFutures([
// 1 Seconds to return results
Future.delayed(Duration(seconds: 1), () {
return "hello 1";
}),
// Throw an exception
Future.delayed(Duration(seconds: 2),(){
throw AssertionError("Error");
}),
// 3 Seconds to return results
Future.delayed(Duration(seconds: 3), () {
return "hello 3";
})
]).listen((data){
print(data);
}, onError: (e){
print(e.message);
},onDone: (){
});
The above code in turn will output :
I/flutter (17666): hello 1
I/flutter (17666): Error
I/flutter (17666): hello 3
The code is simple , I won't go into that .
Thinking questions : since Stream Can receive multiple events , Can it work Stream To implement a subscriber mode event bus ?
Dart and Java And JavaScript contrast
The reason will be Dart And Java and JavaScript contrast , Because , They are typical representatives of strongly typed languages and weakly typed languages respectively , also Dart A lot of places in grammar are also used for reference Java and JavaScript.
1. Dart vs Java
Objectively speaking ,Dart Grammatically, it's better than Java More expressive ; stay VM level ,Dart VM In memory recovery and throughput are repeatedly optimized .
It is worth noting that Dart stay Flutter It is already possible to GC Achieve 10ms within , therefore Dart and Java comparison , The decisive factor won't be performance .
And at the grammatical level ,Dart than Java More expressive , most important of all Dart Support for functional programming is much better than Java
2. Dart vs JavaScript
JavaScript The weak type of has been caught short , therefore TypeScript Even Facebook Of Flow There is a market .
JavaScript It is undoubtedly the best scripting language for dynamic support , For example JavaScript in , You can dynamically extend attributes to any object at any time , For Mastery JavaScript From the top of the world , This is undoubtedly a sharp sword .
however , Everything has two sides ,JavaScript The powerful dynamic feature is also a double-edged sword , You can often hear another voice , Think JavaScript It's a terrible dynamic , Being too flexible makes the code hard to anticipate , There is no way to limit changes that are not expected .
After all, some people are always worried about the code they or others write , They want to be able to make the code controllable , And expect to have a static type checking system to help reduce errors .
Because of this , stay Flutter in ,Dart Almost abandoned the dynamic nature of scripting languages , If reflection is not supported 、 It also does not support dynamic function creation . also Dart from 2.0 Start to force type checking (Strong Mode), The original inspection mode (checked mode) And optional types (optional type) Will fade out , So in terms of type security ,Dart and TypeScript、CoffeeScript It's almost the same , So from the dynamic point of view alone ,Dart There's no obvious advantage , But taken together ,Dart It can be used for server script 、APP Development 、Web Development , That's an advantage !
边栏推荐
- A - Trees on the level(树的层序遍历)
- Chang'an chain learning research - storage analysis wal mechanism
- 堆栈的实现之顺序存储,链式存储
- Maximum heap and heap sort and priority queue
- SQL wrong questions set of Niuke brush questions
- Wechat applet 6 cloud development cloud database
- 初试Dart,笔记
- 天勤第九章课后习题代码
- Top domestic experts gathered in Guangzhou to discuss the safety application of health care data
- Leetcode 1296. Divide the array into a set of continuous numbers (provide an idea)
猜你喜欢

国科大. 深度学习. 期末试题与简要思路分析

Li Hongyi machine learning 2022.7.15 -- gradient descent

Single channel 6Gsps 12 bit AD acquisition and single channel 6Gsps 16 bit Da (ad9176) output sub card based on vita57.1 standard

Leetcode 1275. 找出井字棋的获胜者

1. Basic concepts of DBMS

原始套接字

08_服务熔断Hystrix

Google Earth engine - Classification and processing of UAV images

【花雕动手做】有趣好玩的音乐可视化项目(11)---WS2812幻彩灯带

3U VPX cooling conduction high performance srio/ Ethernet data exchange board
随机推荐
3U VPX cooling conduction high performance srio/ Ethernet data exchange board
csrf防护机制
新基民在支付宝上买基金安全吗
06_服务调用Feign
ORA-00054
06_ Service call feign
国科大.深度学习.期末复习知识点总结笔记
揭开服务网格~Istio Service Mesh神秘的面纱
Behind the high salary of programmers' operation and maintenance
C - matrix chain multiplexing (Application of stack)
BigScience 开源 Bloom 的自然语言处理模型
session管理
Li Hongyi machine learning 2022.07.15 -- error
08_服务熔断Hystrix
您填写的保质期截止当前已经小于10天,不允许发布,若实际保质期大于10天,请如实填写生产日期与进货日期
天天基金上买基金是安全的吗?在线等答案
【xss靶场10-14】见参数就插:寻找隐藏参数、各种属性
How to read and save point cloud data with numpy
Code Runner for VS Code,下载量突破 4000 万!支持超过50种语言
Leetcode 1275. 找出井字棋的獲勝者