【问题标题】:dart, how to define a class so it can be used as a class attribute?dart,如何定义一个类以便它可以用作类属性?
【发布时间】:2014-10-28 11:31:22
【问题描述】:

我在 polymer.dart 中看到他们有:

class CustomTag {
  final String tagName;
  const CustomTag(this.tagName);
}

但它如何与其余代码交互?仅从上面的代码中,我看不出使用@CustomTag('my-tag') 实际上是如何做任何事情的,但会创建一个CustomTag,然后将其作为垃圾收集,因为没有任何东西引用它。

【问题讨论】:

    标签: dart dart-mirrors


    【解决方案1】:

    回答标题中的问题;这些被称为注释;它们只是 const 构造函数。

    回答第二个问题;这些通常用于工具(例如@deprecated)或通过Transformer 重写。您可以在运行时使用 mirrors 访问它们,但这对于转换为 JavaScript 的生产网络应用程序可能不切实际/不可取。

    这里有一些示例代码taken from this answer

    import "dart:mirrors";
    
    void main() {
      var object = new Class1();
      var classMirror = reflectClass(object.runtimeType);
      // Retrieve 'HelloMetadata' for 'object'
      HelloMetadata hello = getAnnotation(classMirror, HelloMetadata);
      print("'HelloMetadata' for object: $hello");
    
      // Retrieve 'Goodbye' for 'object.method'
      var methodMirror = (reflect(object.method) as ClosureMirror).function;
      Goodbye goodbye = getAnnotation(methodMirror, Goodbye);
      print("'Goodbye' for object: $goodbye");
    
      // Retrieve all 'Goodbye' for 'object.method'
      List<Goodbye> goodbyes = getAnnotations(methodMirror, Goodbye);
      print("'Goodbye's for object.method': $goodbyes");
    
      // Retrieve all metadata for 'object.method'
      List all = getAnnotations(methodMirror);
      print("'Metadata for object.method': $all");
    }
    
    Object getAnnotation(DeclarationMirror declaration, Type annotation) {
      for (var instance in declaration.metadata) {
        if (instance.hasReflectee) {
          var reflectee = instance.reflectee;
          if (reflectee.runtimeType == annotation) {
            return reflectee;
          }
        }
      }
    
      return null;
    }
    
    List getAnnotations(DeclarationMirror declaration, [Type annotation]) {
      var result = [];
      for (var instance in declaration.metadata) {
        if (instance.hasReflectee) {
          var reflectee = instance.reflectee;
          if (annotation == null) {
            result.add(reflectee);
          } else if (reflectee.runtimeType == annotation) {
            result.add(reflectee);
          }
        }
      }
    
      return result;
    }
    
    @HelloMetadata("Class1")
    class Class1 {
      @HelloMetadata("method")
      @Goodbye("method")
      @Goodbye("Class1")
      void method() {
      }
    }
    
    class HelloMetadata {
      final String text;
      const HelloMetadata(this.text);
      String toString() => "Hello '$text'";
    }
    
    class Goodbye {
      final String text;
      const Goodbye(this.text);
      String toString() => "Goodbye '$text'";
    }
    

    输出:

    'HelloMetadata' for object: Hello 'Class1'
    'Goodbye' for object: Goodbye 'method'
    'Goodbye's for object.method': [Goodbye 'method', Goodbye 'Class1']
    'Metadata for object.method': [Hello 'method', Goodbye 'method', Goodbye 'Class1']
    

    【讨论】:

    • 谢谢,您是否知道 polymer.dart 如何反映所有加载的库以搜索注释?我想它必须从 initPolymer(); 的某个地方执行此操作,但我看不到它如何自动获取所有已加载库的列表以注册所有 @CustomTag 注释。
    • @0xor1 我相信 Polymer 有一个 Transformer;但恐怕我不熟悉它的工作原理。
    • 我对此也不确定,但我认为 Polymer 和转换器通常使用源镜像和分析器来遍历源代码的 AST(抽象语法树)并替换和/或添加甚至在任何应用程序代码执行之前的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    • 1970-01-01
    • 2020-08-21
    • 2014-03-12
    • 1970-01-01
    • 2010-10-03
    • 2011-04-16
    相关资源
    最近更新 更多