Old iron remember to forward, Brother Cat will present more Flutter good articles ~~~~

Wechat Flutter technology group Ducafecat

The original

Reprom. IO/the – beauty -…

reference

  • The dart. Dev/codelabs/as…
  • Medium.com/flutter-com…
  • The dart. Dev/guides/lang…
  • API. Dart. Dev/stable / 2.13…

The body of the

One of the drawbacks I read most about Flutter is the use of the Dart programming language. It’s not as mature as Kotlin, and this is one of the most frequently cited arguments I’ve read. Dart is a great language in my opinion (and I admit it can be controversial) and I wouldn’t change it for any other language when CREATING apps for Flutter. I say this after Kotlin professionally created Android apps, which is also an elegant and beautiful language, by the way.

In this article, I intend to present four of my favorite features of the Dart programming language, in no particular order; Let’s see how we can use this modern tool:

Null safety

Recently added in Flutter 2.12 (including Flutter 2.0). Air safety is a must in any modern language that pretends to be solid and efficient. That’s why the Dart team has been working on sound null safety, which means we can have nullable types and nullable types, and if we try to perform an unsafe operation later, we’ll get a compile error before the application builds:

// This is a String that can be null
String? nullVar;

// This String cannot be null, the compiler forces me
// to set it a value because of its non-nullable nature.
String nonNullVar = 'I am not null';

// Alternatively, I can specify that the value will be
// set later, but the property continues to be non-nullable.
late String lateNonNullVar;

// If I want to call a method on an instance of a type
// that can be null, I need first to do a runtime check that
// its value is not null.
if(nullVar ! =null) {
  nonNullVar.toLowerCase();
}

// Or call it using the '? ' operator, which means that the
// method will only be called if the instance is not null:nullVar? .toLowerCase();// If the type is not nullable I can safely call any
// method on it directly.
nonNullVar.toLowerCase();

// Always remember to initialize late vars, or you
// will get an exception when trying to access its members.
lateNonNullVar = 'some value';
lateNonNullVar.toLowerCase();
Copy the code

Async / await

Just as in Javascript we have Promises, in Dart we have Futures where async/await is the main keyword, this gives us developers a simple and powerful way to handle asynchronous operations:

With Futures, we can easily stop the current operation flow, wait for an asynchronous operation to complete, and then continue working.

// To specify that a function will perform an asynchronous
// operation (like doing a network request or reading from
// a database) we mark it with the 'async' keyword:
asyncFunction() async {
  // ...
}

// Use the 'await' keyword to stop the flow until the function
// has completed its task:
await asyncFunction();

// You must declare a function as 'async' if it contains
// calls to other async functions:
main() async {
  await asyncFunction();
}

// If the async function returns a value, wrap it within
// a Future. For instance, the following function
// would do a network call and return its result:
Future<NetworkResult> doNetworkCall() async {
  // ...
}

final result = await doNetworkCall();

// But what if the network request fails and an exception
// is thrown? Just wrap the call in a try/catch block:
late NetworkResult result;
try {
  result = await doNetworkCall();
} on NetworkException catch (e) {
  // Handle error
}
Copy the code

It should be noted that even with the async/await keyword, all operations are performed in the same thread, and if we need specific performance requirements, we can use an alternative thread called Generate.

Various methods for defining function parameters

In Dart, we have several options when defining function parameters:

// You can define mandatory parameters as you do in
// many other languages, specifying their type and setting a label:
functionWithMandatoryParameters(String someString, int someNumber) {
  // ...
}

// You are forced to send the defined parameters
// when using the function:
functionWithMandatoryParameters('some_string'.46);

// You can however specify that the parameters are optional:
// (note that the type must be defined as nullable, precisely because
// there's no guarantee that the caller will send a value)
functionWithOptionalParams(
  {String? optionalString, int? optionalNumber}) {
  // ...
}

// You can call this function without sending any values,
// or specifying a value for an optional parameter with its label:
functionWithOptionalParams();
functionWithOptionalParams(optionalString: 'some_string');
functionWithOptionalParams(
  optionalString: 'some_string', optionalNumber: 46);

// When defining optional parameters, you can set a default value
// that will be used in case that there is no value sent by the caller:
functionWithDefaultValue({String someString = 'default'{})// ...
}

// The value of someString is 'default'
functionWithDefaultValue();
// The value of someString is 'some_string'
functionWithDefaultValue(someString: 'some_string');

// Lastly, you can even define mandatory named parameters with the
// 'required' keyword, this is useful to enhance code readability.
createUser(
  {required String username,
  required String name,
  required String surname,
  required String address,
  required String city,
  required String country}) {
// ...
}

createUser(
  username: 'Ghost',
  name: 'John',
  surname: 'Doe',
  address: '3590 Mill Street',
  city: 'Beaver',
  country: 'US');
Copy the code

Composition with mixins

One of the least popular trends in software development is refactoring rather than inheritance, which means adding functionality to a class using component-like elements rather than inheriting from a parent class. This approach allows us to easily add encapsulated functionality without having to deal with complex inheritance hierarchies.

For example, suppose you have a logon logic that you might want to use at different places in your application. You can use this logic to create a component (mixin) and then reuse it as needed:

abstract class AuthUtils {
  Future<User> login() async {
    // Here we can add the login logic that will later be reused
    // in any class that ads this mixin.}}class LoginPage extends StatefulWidget {
  LoginPage({Key? key}) : super(key: key);

  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> with AuthUtils {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<User>(
      future: login(), // Calling the mixin function
      builder: (BuildContext context, AsyncSnapshot<User> snapshot) {
        // ...}); }}Copy the code

The advantage here is that we can add as many mixins as we want, rather than just inheriting from a parent class using inheritance.

conclusion

These are just four of the many useful features Dart offers developers. If you want to learn more, I suggest you visit the Dart Language Tour, which explains every detail of the language in a very friendly way.

The dart. Dev/guides/lang…


The elder brother of the © cat

ducafecat.tech/

github.com/ducafecat

The issue of

Open source

GetX Quick Start

Github.com/ducafecat/g…

News client

Github.com/ducafecat/f…

Strapi manual translation

getstrapi.cn

Wechat discussion group Ducafecat

A series of collections

The translation

Ducafecat. Tech/categories /…

The open source project

Ducafecat. Tech/categories /…

Dart programming language basics

Space.bilibili.com/404904528/c…

Start Flutter with zero basics

Space.bilibili.com/404904528/c…

Flutter combat news client from scratch

Space.bilibili.com/404904528/c…

Flutter component development

Space.bilibili.com/404904528/c…

Flutter Bloc

Space.bilibili.com/404904528/c…

Flutter Getx4

Space.bilibili.com/404904528/c…

Docker Yapi

Space.bilibili.com/404904528/c…