概要
- 使用语句时如何在命名空间中声明变量
use
?(即,没有用变量名声明命名空间) - 如何在没有容器引用的情况下使用“use”语句引用命名空间变量。(即,
trace(foo)
而不是trace(a.foo)
[如果我必须在已经切换到命名空间后声明这一点似乎有点毫无意义])
解释
阅读了 Grant Skinner 的“使用命名空间的完整指南”和其他文章,例如 Jackson Dustan 的“通过命名空间实现更好的 OOP”,我留下了上述未解决的问题。我觉得好像我错过了一些基本原则,但我似乎无法让命名空间工作。以下示例是为与 Flash IDE 一起使用而编写的,因此假设以下...
轨迹.as
package com.atriace {
public namespace locus = "atriace.com";
}
测试A.as
package com.atriace {
public class testA {
import com.atriace.locus;
locus var foo:String = "Apple";
public function testA() {}
}
}
测试B.as
package com.atriace {
public class testB {
import com.atriace.locus;
use namespace locus;
public function testB() {
trace(foo);
}
}
}
文档类:
import com.atriace.testA;
import com.atriace.testB;
var a:testA = new testA();
trace(a.foo); // results in "Apple"
var b:testB = new testB(); // compile error: variable "foo" not defined.
问题 #1
在我看来,命名空间只不过是一个保存具有范围级别访问权限的变量的对象。因此,global 是对所有函数可见的命名空间(因为它是根作用域),local 是命名空间(特定于当前作用域和子作用域),依此类推。如果为真,那么切换到命名空间use
应该允许您简单地声明恰好存在于本地和自定义命名空间中的变量。例如:
use namespace locus
var bar:String = "test"; // this now *should* exist in both local & locus scope/namespace.
由于我不知道像普通对象一样迭代命名空间的方法,我不知道这是否会发生。此外,我还没有看到有人以这种方式声明自定义命名空间变量的任何情况,所以我假设命名空间变量必须始终显式定义。
问题 #2
你可能会问,“这里的目标是什么?” 很简单,我们想要一个动态的变量和方法池,任何新类都可以添加到(在同一个包中)。通过在调用方法之前切换到这个命名空间,我们可以减少代码的冗长。所以,class.method()
就变成了method()
。
在testB.as中,如果我们从未导入testA.as类并实例化它,我们完全可以预料会发生错误;特别是因为 foo 不是类的静态成员(我们也不希望它是)。然而,由于我们至少实例化了一次 foo,所以命名空间locus
现在应该有一个名为 的变量foo
,这意味着当testB.as被实例化并且构造函数为 foo 寻找一个值时,命名空间已经有了一个。
显然,这种想法存在缺陷,因为 Flash 编译器抱怨foo
从未声明过,而我可以foo
从文档类引用的唯一方法是引用容器(即,a.foo
而不是仅仅使用 use 切换到命名空间,并且直接追踪foo
)。
为了论证,继承和静态成员都不是解决这个困境的办法。这既是学习更好的代码技术的练习,也是对具有复杂依赖关系的大型实用程序类结构的回答。鉴于没有变量/方法,您可以简单地围绕它编写代码。
我知道这不是一个有大量文档的主题,这就是为什么我希望这里的一些圣人可以看到我所缺少的。非常感谢您的帮助。:)