Posted by Michael Thomsen, Product Manager, Google Dart Team, on the Official Dart Blog on May 12, 2022

With the release of Flutter 3 at this I/O conference, we also officially released the Dart 2.17 stable SDK at the same time. This release is built around our core themes: leading productivity and platform portability.

Dart 2.17 provides new language features: enumeration support for member variables, improved superclass parameter inheritance, and more flexible named parameters . We also opened the 2.x version for package:lints , which is a set of official lint rules, which is a lint rule set integrated according to our summary of Dart best practices. At the same time, we also updated the API documentation of the core library with rich sample code. And, to improve platform integration features, we have provided a new template in the Flutter plugin, using dart:ffi to interoperate with native platforms in C language, provide experimental support for the RISC-V instruction set, and Signing support for macOS and Windows executables.

New features of programming languages boost productivity

We have been continuously improving the Dart programming language, adding new features and improving existing ones to help developers work more efficiently. Dart 2.17 adds support for enum member variables, optimizes the way named parameters are used in constructors, and starts using parameters from inherited superclasses to reduce verbose and repetitive code.

Enhanced support for enumeration of member variables

Enums are great for representing a discrete set of states. For example, we can describe water as enum Water { frozen, lukewarm, boiling } . But what if we want to add some methods on enum , for example, to convert each state to temperature and support to convert enum to String ? Maybe we could use extension methods to add a waterToTemp() method, but we must always keep an eye on its synchronization with enum . For String we would like to override the toString() method, but it does not support this.

Member variables of enum types are now supported in Dart 2.17. This means that we can add fields that hold state, constructors that set state, methods that have functionality, and even override existing methods. This has been a constant demand from many developers in the community, and this is our #3 voted issue in the Dart programming language repository's issue tracker.

Continue to take Water for example, we can add a int field that holds the temperature, and add a default constructor that receives int :

 enum Water 
  const Water(this.tempInFahrenheit);

  final int tempInFahrenheit;
}

To ensure that the constructor is properly called when the enum is created, we need to append an explicit call to each enum value:

 enum Water {
  frozen(32),
  lukewarm(100),
  boiling(212);
}

String ,我们可以toString方法, enums也继承自Object :

 @override
String toString() => "The $name water is $tempInFahrenheit F.";

This way, you have a fully functional enum class that can be easily instantiated and methods that can be called anywhere:

 void main() {
  print(Water.frozen); // 打印内容为 “The frozen water is 32 F.”
}

Full examples of both methods are shown below, with these changes the new version of the code is easier to read and maintain.

superclass initializer

When your code has type inheritance, a common practice is to pass some constructor parameters to the superclass's constructor. For this the subclass needs to 1) list each parameter in its constructor 2) call the superclass's constructor with those parameters. This resulted in a lot of code duplication, making the code difficult to read and maintain.

Several Dart community members helped Dart achieve this language goal. Six months ago, GitHub user @roy-sianez submitted a language issue . His suggestion is similar to an earlier suggestion by GitHub user @apps-transround : maybe we can fix this by introducing a new way to indicate that a parameter is specified in the superclass. We thought this was a good idea, so it was implemented and added to Dart 2.17. As you can see from the examples below, this has a strong correlation with the code of the Flutter widget. In fact when we applied this feature to the Flutter framework, we saw a total reduction of almost 2,000 lines of code in the framework!

Named parameters can be used in any parameter position

Finally, we improved the way parameters are named when calling methods. Before this update, calls with named parameters had to appear after the normal parameter list. It's very frustrating when you want to improve code readability and want to write named parameters first but it doesn't work. For example below List<T>.generate constructor call. Before this update growable the parameter had to be last, which would cause the parameter to be easily missed by a constructor parameter that could have a lot of content. Now you can order them to your liking, you can use named parameters first and generator parameters last.

For more examples of these three improvements, see our updated enumerations , superclass initialization constructs , and named parameter sample code.

Productivity tool improvements

Going back to the topic of productivity, we've made some improvements to the core tools around productivity.

In Dart 2.14, we introduced package:lints which works with the Dart analyzer to prevent you from writing bad code and review your Dart code with more formal rules. Many more code hinting rules have been added to the analyzer since then, and we have carefully categorized them and selected 10 new code hinting rules for all Dart code , and 2 new ones specifically for Flutter code. Code hinting rules . They include code hinting rules to ensure that the packages you import are properly declared in your pubspec file, prevent the abuse of null checks on type parameters, and ensure consistent formatting of subproperties. You can simply upgrade to the new lints package using the command:

  • For Dart packages you can use:
    dart pub upgrade —-major-versions lints
  • For Flutter packages you can use:
    flutter pub upgrade —-major-versions flutter_lints

SecureSockets Typically used to enable TCP socket connections secured with TLS and SSL. Before Dart 2.17, debugging these encrypted connections during development was tricky because there was no way to inspect secure data traffic. Now we've added support for specifying keyLog files, when specified, a line of text in the NSS key log format will be appended to the file when a new TLS key is exchanged with the server. This will enable network traffic analysis tools such as Wireshark to decrypt what is sent over the socket. See the API documentation for SecureSocket.connect() for more details.

dart doc The generated API documentation is one of the important things for most Dart developers to learn a new API. While our core library APIs have long had rich textual descriptions, many developers tell us they prefer to learn the API by reading sample code. In Dart 2.17, we checked out all the major core libraries and added detailed example code for the top 200 pages viewed. You can compare dart:convert to see these changes on the Dart 2.16 and 2.17 documentation pages, hopefully these changes will help you make better use of the API documentation.

Helping productivity is not only about adding, but also doing subtraction. We cleaned up some accumulated content and removed the deprecated APIs in the SDK, which will help us keep the code size smaller, which is good for newcomers developers are especially important. To do this, we removed 231 lines of deprecated code from the dart:io library. If you are still using these deprecated APIs, you can use dart fix to fix and replace. We are still working on removing the deprecated Dart CLI tools , this update removes the dartdoc tool (use dart doc instead) and pub tool ( dart pub or flutter pub instead).

Expanded platform integration and support

The second core theme is platform integration and support. Dart is a true multi-platform language. While we already support a large number of platforms , we are constantly expanding into new platforms to ensure you can deeply integrate with each supported platform, while also keeping an eye on more emerging platforms.

Our core mechanism for interoperating with C or native code , Dart FFI, is a popular way to integrate Dart code with existing native platform code. On Flutter, FFI is a great way to build plugins that use the host platform's native API (such as the Windows win32 API). In Dart 2.17 and Flutter 3, we added templates for FFI to the flutter tool, now you can easily create FFI plugins with Dart calling native code support via dart:ffi API. See the developer documentation developing packages and plugins page for details.

FFI now supports ABI-specific types, you can use FFI on platforms with specific ABI (application binary interface) ") types. For example, now you can use Long (--- in C language long ) correctly represents a long integer with an ABI-specific size, the result may be 32-bit or 64-bit due to differences in CPU architecture. See the list of "Implementers" in the AbiSpecificInteger API page for a full list of supported types.

When using Dart FFI to deeply integrate with native platforms, it is sometimes necessary to align the cleanup behavior of Dart allocated memory or other resources (ports, files, etc.) with native code. This problem has long been tricky because Dart is a language that handles garbage collection cleanup automatically. In Dart 2.17, we solved this problem by introducing the concept of Finalizer, which includes a Finalizable marker interface to "mark" objects that should not be prematurely finalized or discarded, and a NativeFinalizer Can be attached to Dart objects, providing callbacks to run when the object is about to be garbage collected. Finalizers run cleanup in both native and Dart code. See the description and examples in the NativeFinalizer API documentation for more details, or WeakReferences and similar support for Finalizer in Dart code.

Support for compiling Dart to native code is also at the heart of enabling Flutter apps to have great startup performance and fast rendering. In addition, you can use dart compile to compile Dart files into executable files. These executables can be run standalone on any machine without installing the Dart SDK. Another new feature in Dart 2.17 is support for signing executables, and the resulting artifacts can be deployed on Windows and macOS where signing is often required.

We also remain at the forefront of emerging platforms, continuing to expand the set of platforms we support. RISC-V is a brand new instruction set system. RISC-V International is a global non-profit organization that owns the RISC-V specification, making the instruction set free and open. It's still an emerging platform, but we're excited about its potential, so our 2.17.0–266.1.beta Linux release includes experimental support for it. We want to hear your feedback and you can ask questions or share your experience!

Get started with Dart 2.17!

We hope Dart's 2.17 official release will impress you and help you improve your productivity, as well as bring your applications to more platforms. Download Dart 2.17 and get started now, also install and use Flutter 3, using the built-in Dart SDK.


Original link :

https://medium.com/dartlang/dart-2-17-b216bfc80c5d

Localization : CFUG Team

Chinese link : https://flutter.cn/posts/dart-2-17


Flutter
350 声望2.5k 粉丝

Flutter 为应用开发带来了革新: 只要一套代码库,即可构建、测试和发布适用于移动、Web、桌面和嵌入式平台的精美应用。Flutter 中文开发者网站 flutter.cn