首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >省道中的镜子并不适用于所有元素。

省道中的镜子并不适用于所有元素。
EN

Stack Overflow用户
提问于 2014-01-31 20:09:50
回答 2查看 238关注 0票数 3

我在飞镖中使用反射(也称省道:镜子)。首先:这里看到的所有代码在dartium中都能很好地工作(使用dart本机),但只有在用dart2js编译并在chrome中运行时才能部分工作。

我有一个名为BinaryReader的类,而不是从字节流中读取类。下面是这样做的代码(去掉重复部分):

代码语言:javascript
复制
  void readObject(dynamic obj) {
    var inst = reflect(obj);
    inst.type.declarations.forEach((Symbol name, DeclarationMirror decl) {
      if(decl is VariableMirror) {
        var variable = decl;
        if(variable.metadata.length == 0) {
          return;
        }

        InstanceMirror attrib = variable.metadata.first;
        if(attrib.hasReflectee == false) {
          return;
        }

        if(attrib.reflectee is Field) {
          var field = attrib.reflectee as Field;
          var value;
          switch(field.type) {
            case I8: 
              value = getInt8();
              break;

            // ...

            case V3:
              value = new Vector3(getFloat(), getFloat(), getFloat());
              break;

            default:
              value = null;
              break;
          }

          if(value == null) {
            return;
          }

          inst.setField(name, value);
        }
      }
    });
  }

导入镜像的方式如下:

代码语言:javascript
复制
import 'model/M4SubMesh.dart';
import 'model/M4Model.dart';
import 'package:vector_math/vector_math.dart';
@MirrorsUsed(targets: const["M4SubMesh", "M4Model", "vector_math"], override: '*')
import 'dart:mirrors';

M4SubMesh和M4Model是各自省道文件的库名。vector_math,vector_math.dart的

首先,我从流中读取了M4Header的一个实例,它是M4Model库的一部分。所有的值都是正确的,如下所示:

代码语言:javascript
复制
class M4Header
{
  @Field(UI32)
  int Signature;
  @Field(UI32)
  int Version;
  @Field(UI32)
  int numSubMeshes;
  @Field(UI32)
  int ofsSubMeshes;  
}

然后,我尝试阅读一个M4SubMeshHeader,它如下所示:

代码语言:javascript
复制
class M4SubMeshHeader
{
  @Field(UI32)
  int gridX, gridY, gridZ;
  @Field(F32)
  num blockSize;
  @Field(V3)
  Vector3 bboxMin, bboxMax;
}

阅读后,blockSize有一个随机值。bboxMin和bboxMax为空。这里出什么问题了?

你好,克罗蒙

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-31 23:51:50

找到解决办法了!注释只适用于声明列表中的第一个元素。因此,上面的示例实际上扩展到:

代码语言:javascript
复制
class M4SubMeshHeader
{
  @Field(UI32)
  int gridX;
  int gridY;
  int gridZ;
  @Field(F32)
  num blockSize;
  @Field(V3)
  Vector3 bboxMin;
  Vector3 bboxMax;
}

在我看来,这可以被认为是一个错误,我看一下文档,如果没有提到它,就报告它。最后,blockSize变成了应该分配给gridY的值,这使得它看起来像随机的。但是-老实说-我也得承担一些责任。'bboxMin和bboxMax是空的‘,这是错误的,bboxMin不是空的,但是有无效的值,但是当我在代码中留下一行时,我在打印它之前使用了bboxMax,我认为它已经在bboxMin崩溃了。

你好,克罗蒙

票数 1
EN

Stack Overflow用户

发布于 2014-02-01 06:05:14

我认为relection librarylanguage specification之间是不匹配的。

来自语言规范:

元数据可以出现在库、部件头、类、类型参数、构造函数、工厂、函数、字段、参数或变量声明之前,也可以出现在导入、导出或部件指令之前。

也就是说,metadata可以出现在variable declaration之前。

现在来看一下variable declaration定义。

代码语言:javascript
复制
variableDeclaration:
     declaredIdentifier (',' identifier)*
   ;
declaredIdentifier:
     metadata  finalConstVarOrType identifier

也就是说,variable declaration可以由以下几个部分组成:

  • 元数据,适用于此声明。
  • 最终/const/var/类型说明符
  • 此声明中的标识符列表。

这意味着一个variable declaration可以声明无限数量的变量。

但它仍将是一项声明,但在一项声明中不会有多少不同的声明。

这只意味着这个variable declaration声明了一个set of variables

此外,如果metadata可以出现在variable declaration之前,则必须将其应用于此声明中的所有元素。

这是因为,作为状态语言规范,metadata只能出现在declaration之前,而不能出现在声明中的某些part之前。

这是因为,作为states规范,我们有一个变量声明而不是三个变量声明,它声明了这个声明中的三个变量。

代码语言:javascript
复制
var a, b, c;

因此,如果注释这个变量声明。

代码语言:javascript
复制
@Foo var a, b, c;

然后,按照states规范,如果元数据可以在变量声明之前附加,那么这个元数据必须应用于整个声明,而不仅仅是这个声明中的第一个元素。

附注:

根据本文件可得出的结论如下:

https://www.dartlang.org/docs/spec/latest/dart-language-specification.html

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21489135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档