简体   繁体   中英

"#define" equivalent in Dart/Flutter?

I wonder if there is a way to #define short_expression long_expression in Dart/Flutter?

For example, instead of typing

MediaQuery.of(context).size.width
// or 
Locale.of(context).translate("x")

in every build function, we can

#define MQWidth MediaQuery.of(context).size.width
// or
#define Lt(x) Locale.of(context).translate("x")

then use it in every build function instead?

Macros. Generative programming aka metaprogramming is usually not a thing in interpreted languages. The closest thing to generative programming concept in dart would be static metaprogramming that is actively being chased by. You can currently achieve source code generation in dart via build_runner , which I believe you have seen for example in packages such as json_serializable , and retrofit . But it's still way too far from perfect and requires a lot of work to achieve something even minuscule. And it only fits into certain scenarios and the example you gave is sadly not one of them.

So, the answer is no . You can't do that, at least as of now.

But instead why don't you just separate that into functions if they are really overused all over the place. I know you still have to pass in the context everywhere which is kinda cluttering compared to what you have expected. But it'll still make the code much shorter, if that's your goal.

Hope this answers your question. Cheers!

An example of how this can be done.
By the way, this is the simplest example. Without using of the macro arguments (AST nodes).

Input: bin/main.dart

@pragma('meta_expression:build')
library my_cool_library;

@pragma('meta_expression:import')
import 'package:test_meta_expression/my_cool_macros.dart';

void main(List<String> args) {
  final a = mqWidth();
  final b = lt('Hello!');
  print(a);
  print(b);
}

Output: bin/main.impl.dart

// GENERATED CODE - DO NOT MODIFY BY HAND

// **************************************************************************
// MetaExpressionLibraryGenerator
// **************************************************************************

library my_cool_library;

void main(List<String> args) {
  //
  final a = MediaQuery.of(context).size.width;
  final b = Locale.of(context).translate('Hello!');
  print(a);
  print(b);
}

Macro: package:test_meta_expression/my_cool_macros.dart

import 'package:meta_expression_annotation/meta_expression_annotation.dart';

@MetaExpression(mqWidthImpl)
external int mqWidth();

String mqWidthImpl(MetaContext context) => '''
MediaQuery.of(context).size.width
''';

@MetaExpression(ltImpl)
external String lt(String x);

String ltImpl(MetaContext context) => '''
Locale.of(context).translate(x)
''';

File: pubspec.yaml

dependencies:
  meta_expression_annotation: 0.2.1
dev_dependencies:
  build_runner: any
  meta_expression: 0.2.1

Build command:

dart run build_runner build

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM