Dart Metadata 使用

Dart Metadata 使用

Dart提供了类似于Java注解一样的机制 metadata ,通过使用 metadata 可以实现与注解一样的功能,中文我们称它为元数据。我们来看一段官方的使用描述:

Metadata can appear before a library, class, typedef, type parameter, constructor, factory, function, field, parameter, or variable declaration and before an import or export directive.

这段话是说 Metadata 可以出现在库、类、typedef,参数类型,构造函数,工厂构造函数,方法,字段,参数,或者变量和 import 以及 export 指令前面。可见 metadata 使用范围之广。

Guide

原文档在这里

官方给了我们定义的例子:

Use metadata to give additional information about your code. A metadata annotation begins with the character @, followed by either a reference to a compile-time constant (such as deprecated) or a call to a constant constructor.

Two annotations are available to all Dart code: @deprecated and @override. For examples of using @override, see Extending a class. Here’s an example of using the @deprecated annotation:

class Television {
  /// _Deprecated: Use [turnOn] instead._
  @deprecated
  void activate() {
    turnOn();
  }

  /// Turns the TV's power on.
  void turnOn() {...}
}

You can define your own metadata annotations. Here’s an example of defining a @todo annotation that takes two arguments:

library todo;

class Todo {
  final String who;
  final String what;

  const Todo(this.who, this.what);
}

And here’s an example of using that @todo annotation:

import 'todo.dart';

@Todo('seth', 'make this do something')
void doSomething() {
  print('do something');
}

Metadata can appear before a library, class, typedef, type parameter, constructor, factory, function, field, parameter, or variable declaration and before an import or export directive. You can retrieve metadata at runtime using reflection.

但是这里并没有说怎么使用 reflection ,下面我们来看看怎么使用反射获取 metadata 。

Mirrors

为了能够使用反射 dart 引入了 mirrors 系统,在 dart:mirrors 包下。这里我们主要讲跟类相关的,包括:

InstanceMirror
ClassMirror
DeclarationMirror
ParameterMirror
MethodMirror
TypeMirror

获取 mirror 的方法:

InstanceMirror reflect(Object)
ClassMirror reflectClass(Type)
TypeMirror reflectType(Type)

下面是一个获取 metadata 的 demo:

main(List<String> args) {
  getWorkAnnotation();
}

void getWorkAnnotation() {
  ClassMirror classMirror = reflectClass(TestMixin);

  // 获取 class 上的元数据
  classMirror.metadata.forEach((metadata) {
    print(metadata.reflectee.who + ' ==> ' + metadata.reflectee.what);
  });

  // 获取 field 和 method 上的元数据
  classMirror.declarations.forEach((Symbol key, DeclarationMirror value) {
    if (value is MethodMirror) {
      if (value.simpleName == #getRequest) {
        value.metadata.forEach((metadata) {
          if (metadata.reflectee is Todo) {
            print(metadata.reflectee.who + ' ==> ' + metadata.reflectee.what);
          } else if (metadata.reflectee is TestAnnotation) {
            print(metadata.reflectee.id.toString() +
                ' ==> ' +
                (metadata.reflectee.name == null
                    ? 'null'
                    : metadata.reflectee.name));
          } else if (metadata.reflectee is GET) {
            print(metadata.reflectee.value);
          }
        });

        // 获取方法中参数上的元数据
        value.parameters.forEach((param) {
          param.metadata.forEach((metadata) {
            if (metadata.reflectee is Query) {
              if (metadata.reflectee.value == null) {
                print(
                    'args name ==> ' + MirrorSystem.getName(param.simpleName));
              } else {
                print(metadata.reflectee.value);
              }
            }
          });
        });
      }
    }
  });
}

@Todo('wyndam', 'work')
abstract class TestMixin {
  @GET(value: 'https://www.baidu.com/')
  void getRequest(@Query(value: 'q') String param);
}

class GET {
  final String value;

  const GET({this.value});
}

class Todo {
  final String who;
  final String what;

  const Todo(this.who, this.what);
}
### 回答1: 在 Dart 中,你可以使用递归来解决一些问题。递归是一种在函数中调用自己的编程技术。 举个例子,假设你想要编写一个函数来计算阶乘。你可以使用递归来实现这个函数,这样可以使代码更加简洁。 这是一个使用递归计算阶乘的示例代码: ``` int factorial(int n) { if (n <= 1) { return 1; } return n * factorial(n - 1); } void main() { print(factorial(5)); // prints 120 } ``` 在这个示例中,我们定义了一个名为 `factorial` 的函数,它接受一个整数 `n` 作为参数。如果 `n` 小于等于 1,则返回 1;否则,它会调用自身并返回 `n` 乘以 `factorial(n - 1)` 的结果。这样,每次调用都会使 `n` 减少 1,直到 `n` 小于等于 1,此时函数就会停止递归并返回结果。 递归是一种非常有用的编程技术,但是你需要注意,如果不小心使用递归,它可能会导致无限递归。因此,在使用递归时,你需要确保设置了一个“出口”条件,以便在递归达到一定深度时停止递归。 ### 回答2: Dart是一种面向对象的编程语言,也支持递归(即在函数内部调用函数自身)。 使用递归的关键是定义递归函数及其终止条件。以下是一个使用递归的示例,计算n的阶乘: ```dart int factorial(int n) { // 终止条件 if (n == 0) { return 1; } // 递归调用 return n * factorial(n - 1); } void main() { int n = 5; int result = factorial(n); print('$n 的阶乘是 $result'); } ``` 在上述代码中,`factorial` 函数调用自身,并通过传递 `n-1` 的值进行递归调用,直到 `n` 的值为 0,即达到了终止条件。递归函数不断进入下一层,直到满足终止条件后返回最终结果。 使用递归时需要注意避免出现无限递归的情况,即确保递归调用的条件能够最终达到终止条件,否则程序会陷入无限循环。此外,递归可能会占用大量的内存,对于复杂或大规模的问题,可能需要考虑使用其他解决方案来优化性能。 ### 回答3: Dart是一种高级编程语言,它支持递归函数的使用。递归是一种在函数中调用自身的技术,它可以解决那些可以被分解为较小同类型问题的问题。 在Dart中,要使用递归,需要注意以下几点: 1. 将递归函数定义为一个函数: ```dart int factorial(int n){ if(n == 0){ return 1; }else{ return n * factorial(n-1); } } ``` 上述代码中定义了一个名为"factorial"的递归函数,计算一个数的阶乘。 2. 在递归函数中,必须有一个终止条件。终止条件是函数停止调用自身的条件。在上述例子中,当n等于0时,终止条件被满足,递归停止。 3. 在递归函数中,调用自身,但是要确保在每次调用时,问题规模都会减小。在上述例子中,递归调用了`factorial(n-1)`,使得问题规模每次减少1。 使用递归可以简洁地解决某些问题,但是需要注意递归深度。如果递归深度太大,可能会导致栈溢出。因此,要谨慎使用递归,并确保有合适的终止条件和问题规模的减小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值