Flutter现代命名风格插件nameof_modern的使用
Flutter现代命名风格插件nameof_modern的使用
标题
Nameof Modern
内容
在某些情况下,项目需要访问编程语言实体的名字,如方法、属性、构造函数等。不幸的是,今天Flutter没有为这个目的设计的反射机制。但是有代码生成!这个包使用代码生成来帮助访问类、方法等实体的名字。这个包是原始包nameof
的更新版。nameof_modern
完全基于nameof
代码,感谢nameof
作者❤️。nameof_modern
进行了更新,并且包含了最新的功能以确保新2024和未来项目的正常运行。这个包是新的,并且在社区的帮助下我们正在改进它❤️。
🗒️重要提示: 这个包是基于
nameof
包创建的。nameof
是一个为Dart类成员(如字段、属性、方法和构造函数)生成名称的生成器。nameof_modern
完全基于nameof
代码,感谢nameof
作者❤️。
安装指南
为了使用nameof_modern
,你需要你的典型build_runner
代码生成设置。
首先,安装build_runner
和nameof_modern
,并将其添加到你的pubspec.yaml
文件中:
-
如果你正在创建一个Flutter项目:
$ flutter pub add nameof_annotation_modern $ flutter pub add --dev build_runner $ flutter pub add --dev nameof_modern
-
如果你正在创建一个Dart项目:
$ dart pub add nameof_annotation_modern $ dart pub add --dev build_runner $ dart pub add --dev nameof_modern
这将安装三个包:
build_runner
,用于运行代码生成器的工具nameof_modern
,代码生成器nameof_annotation
,包含nameof_modern
注解的包。
运行代码生成器
要运行代码生成器,请执行以下命令:
dart run build_runner build
对于Flutter项目,你也可以运行:
flutter pub run build_runner build
请注意,像大多数代码生成器一样,nameof_modern
需要你导入注解(nameof_annotation_modern
)并使用part
关键字在文件顶部。
例如,一个想要使用nameof_modern
的文件将从以下开始:
import 'package:nameof_annotation_modern/nameof_annotation_modern.dart';
part 'my_file.nameof.dart';
使用nameof_modern
简单使用
例如我们有一个类Movie
。为了生成这个类的名字,你需要告诉生成器一些指令使用nameof_modern
注解:
@nameof
class Movie {
final String title;
final String description;
final int year;
final String coverUrl;
Movie(this.title, this.description, this.year, this.coverUrl);
}
然后你需要运行生成器。
它将生成以下代码:
/// Container for names of elements belonging to the [Movie] class
abstract class NameofMovie {
static const String className = 'Movie';
static const String constructor = '';
static const String fieldTitle = 'title';
static const String fieldDescription = 'description';
static const String fieldYear = 'year';
static const String fieldCoverUrl = 'coverUrl';
}
然后在你的代码中使用它:
print(NameofMovie.fieldTitle);
print(NameofMovie.fieldDescription);
print(NameofMovie.fieldYear);
print(NameofMovie.fieldCoverUrl);
很简单!
你也可以为抽象类和混入使用nameof
注解。
模型覆盖
你可以通过使用覆盖设置和@NameofIgnore
注解非常精确地设置模型成员的覆盖。例如,下面两种配置将导致相同的输出。
- 第一种配置:
[@Nameof](/user/Nameof)(coverage: Coverage.excludeImplicit) class Movie { final String title; final String description; @nameofKey final int year; @nameofKey final String coverUrl; Movie(this.title, this.description, this.year, this.coverUrl); }
- 第二种配置:
输出:[@Nameof](/user/Nameof)(coverage: Coverage.includeImplicit) class Movie { @nameofIgnore final String title; @nameofIgnore final String description; final int year; final String coverUrl; @nameofIgnore Movie(this.title, this.description, this.year, this.coverUrl); }
注意/// Container for names of elements belonging to the [Movie] class abstract class NameofMovie { static const String className = 'Movie'; static const String fieldYear = 'year'; static const String fieldCoverUrl = 'coverUrl'; }
coverage
设置,@nameofKey
和@nameofIgnore
注解。 如果你不设置覆盖,则生成器将默认使用includeImplicit
设置。
覆盖名称
如果你想覆盖元素的名称,可以这样做! 代码:
@nameof
class Ephemeral {
@NameofKey(name: 'AbRaCadabra')
String get flushLight => 'Purple';
}
生成器输出:
/// Container for names of elements belonging to the [Ephemeral] class
abstract class NameofEphemeral {
static const String className = 'Ephemeral';
static const String constructor = ''
static const String propertyGetFlushLight = 'AbRaCadabra'
}
如你所见,属性被重命名了。输出中的名称是AbRaCadabra
而不是flushLight
。
名称目标
@NameofKey
注解应用于公共字段、方法、属性和构造函数。
配置
nameof
提供了多种自定义生成代码的方法。例如,你可能希望更改模型的覆盖行为。
要实现这一点,有两种可能性:
更改特定模型的行为
如果你想只针对一个特定的类自定义生成代码,可以通过注解设置来实现:
[@Nameof](/user/Nameof)(coverage: Coverage.excludeImplicit
class Employee {...}
更改整个项目的整体行为
相反,如果你不想对单个类进行修改,你可能希望同时对所有nameof
模型进行修改。
你可以通过自定义名为build.yaml
的文件来实现这一点。这个文件应该放在你的pubspec.yaml
文件旁边:
project_folder/
pubspec.yaml
build.yaml
lib/
在那里,你可以通过编写:
targets:
$default:
builders:
nameof:
options:
coverage: includeImplicit
更多关于Flutter现代命名风格插件nameof_modern的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter现代命名风格插件nameof_modern的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用nameof_modern
插件的一个示例。nameof_modern
插件允许你获取变量、类、函数等的字符串名称,这在调试或生成动态UI时非常有用。尽管Dart本身并不原生支持类似C#的nameof
运算符,但nameof_modern
插件通过宏和构建时代码生成提供了类似的功能。
首先,确保你已经在pubspec.yaml
文件中添加了nameof_modern
依赖:
dependencies:
flutter:
sdk: flutter
nameof_modern: ^最新版本号 # 替换为实际的最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,你可以在你的Flutter项目中使用nameof_modern
。以下是一个简单的示例,展示了如何获取变量和函数的名称:
import 'package:flutter/material.dart';
import 'package:nameof_modern/nameof_modern.dart';
part 'main.nameof.g.dart'; // 引入生成的文件
@NameOfClass() // 标记类以生成名称
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
String appName = 'Flutter App'; // 要获取名称的变量
return MaterialApp(
title: getNameOf(appName), // 获取变量名称
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text(getNameOf(appName)),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'${getNameOf(_incrementCounter)} button pressed ${_counter} times',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
),
);
}
int _counter = 0;
@NameOfFunction() // 标记函数以生成名称
void _incrementCounter() {
setState(() {
_counter++;
});
}
}
void main() {
// 生成名称的代码(通常在构建脚本中自动运行)
generateNameOfFile(MyApp);
runApp(MyApp());
}
注意:上面的代码中有几个重要的点需要注意:
-
part 'main.nameof.g.dart';
:这是生成的代码文件的引入。实际使用时,你需要确保在构建过程中生成这个文件。这通常是通过构建脚本或IDE插件自动完成的。 -
@NameOfClass()
和@NameOfFunction()
:这些注解用于标记类和函数,以便nameof_modern
插件可以生成它们的名称。但是,请注意,nameof_modern
插件的具体API和使用方式可能会根据版本有所不同。上述注解和用法是基于假设的,因为实际的nameof_modern
插件可能需要不同的配置或使用方式。 -
generateNameOfFile(MyApp);
:这是一个假设的函数调用,用于生成包含名称信息的代码。在实际使用中,你需要根据nameof_modern
插件的文档来配置构建脚本或IDE,以便在构建过程中自动生成这些文件。
由于nameof_modern
插件的具体实现和API可能会随着版本更新而变化,因此强烈建议查阅该插件的官方文档和示例代码,以确保正确理解和使用。如果插件提供了命令行工具或构建脚本示例,请按照提供的指南进行配置。