在注释中插入字符串 class

Interpolate String within an annotation class

我试图找到一种在注释中插入字符串的方法,因为注释 class 构造函数的参数必须是常量我不得不跳过 $,然后替换'$''$' 每当我需要插值时,下面的示例阐明了我正在尝试做的事情

import 'dart:mirrors';

    void main() {
          var c = new Chicken('aaaa','blue',99);
          var templateValue = (reflectClass(Chicken).metadata.where((a)=>a.reflectee.runtimeType == Template).first.reflectee as Template).value;
          print(interpolater.interpolate(c,templateValue));
        }

        class Template{
          final String value;
          const Template(this.value);
        }

        @Template('<div>name:${context.name} color:${context.color} age:${context.age}</div>')
        class Chicken{
          String name;
          String color;
          int age;
          Chicken(this.name,this.color,this.age);
        }

        class interpolater{
          static String interpolate(Object context,String s){
            s = s.replaceAll('\$', '$'); 
            return s;
          }
        }

但它似乎不起作用,无论如何要使类似的东西起作用?

您需要将字符串包装在如下 templateStr 的函数中:

import 'dart:mirrors';

class Context {
  String name = "some name";
  String color = "some color";
  int age = 15;
}

void main() {
  var c = new Chicken('aaaa','blue',99);
  var templateValue = (reflectClass(Chicken).metadata.where((a)=>a.reflectee.runtimeType == Template).first.reflectee as Template).value(c);
  print(templateValue);
}

class Template{
  final Function value;
  const Template(this.value);
  String getValue(context) => value(context);
}

String templateStr(context) => '<div>name:${context.name} color:${context.color} age:${context.age}</div>';

@Template(templateStr)
class Chicken{
  String name;
  String color;
  int age;
  Chicken(this.name,this.color,this.age);
}

字符串插值是Dart的语法部分,在解析时识别。

如果您获取一个字符串并将字符串中的“\$”替换为“$”,您将得到一个包含“$”的字符串。它在编译时不是插值,所以现在不是插值。

您可以将“$a foo $b”之类的字符串插值视为 "" + a.toString() + " foo " + b.toString() + "" 的 shorthand。字符串插值是一个 字符串表达式 ,但它本身并不是一个字符串 - 每次对其求值时,它都会求值为 new 字符串。 (好吧,编译时常量字符串插值在运行时是一个字符串值,因为它只在编译时求值一次)。

如果你想制作一个在运行时填充的模板,那么你还必须制作填充的代码。

一种替代方法是不使用字符串,而是在注释中使用函数:

// Top-level function is compile-time constant.
myTemplate(context) => 
  '<div>name:${context.name} color:${context.color} age:${context.age}</div>';

@Template(myTemplate)
class Chicken {...}

然后就可以像现在一样从注解中提取函数,然后用鸡叫了。这使用真正的字符串插值来构建字符串,并延迟评估,直到您有可用的上下文。

(如果您有权注释 class,为什么不直接向 class 添加一个方法。那么您将不需要镜像。或者如果您不需要不想给对象添加方法,也许让它成为静态的,然后使用镜像查找它)