范围冲突:同名的全局函数和类方法

发布于 2024-11-19 06:17:38 字数 696 浏览 3 评论 0原文

我的问题直接涉及 ActionScript 3,尽管它可能会出现在其他语言中。

考虑 AS3 中的全局 trace 函数。调用该方法不需要导入,并且可以从所有类全局使用。

class A {

    public function A() {
        trace("Hello, A!"); // Hello, A!
    }

}

现在,如果我创建自己的同名类方法会怎样?在 AS3 中,如果我有一个类方法 trace,然后在类中的其他位置调用 trace,则该调用是通过全局函数对类方法进行的。本质上,我已经阻止了调用全局跟踪方法的能力。

class B {

    public function B() {
        trace("Hello, B!"); // no output
    }

    public function trace(s:String):void {
        // do something else.
    }

}

现在,我知道明显的答案是“不要创建名为 trace 的类方法”。但是如果我不知道全局 trace 函数的存在怎么办?或者,如果我想要“覆盖”或“阻止”全局函数怎么办?难道编程就那么糟糕吗?或者这只是 AS3 是一种糟糕的面向对象语言的另一个例子?

My question deals directly with ActionScript 3, although it could possibly appear in other languages.

Consider the global trace function found in AS3. Calling the method requires no imports and is globally available from all classes.

class A {

    public function A() {
        trace("Hello, A!"); // Hello, A!
    }

}

Now, what if I create my own class method of the same name? In AS3, if I have a class method trace and then make a call to trace elsewhere in my class, the call is made to the class method over the global function. Essentially, I've blocked my ability to call the global trace method.

class B {

    public function B() {
        trace("Hello, B!"); // no output
    }

    public function trace(s:String):void {
        // do something else.
    }

}

Now, I know the obvious answer is to say, "don't create a class method called trace." But what if I'm unaware of the existence of the global trace function? Or what if I have a desire to "override" or "block" the global function? Is doing so bad programming? Or is this just another example of how AS3 is a poor object oriented language?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

水溶 2024-11-26 06:17:38

导入 flash.uitls.*;

那么你可以使用

(getDefinitionByName('trace') as Function)('Global trace.');

import flash.uitls.*;

then you can use

(getDefinitionByName('trace') as Function)('Global trace.');
幻想少年梦 2024-11-26 06:17:38

如果您的函数 trace 不是 public,您可以使用 public 命名空间 调用原始函数:

class B {
    public function B() {
        // call the trace function that is defined in the public namespace
        public::trace("Hello, B!"); // output "Hello, B!"
    }

    // here the function is protected so not into the public namespace
    protected function trace(s:String):void {
        // do something else.
    }
}

If your function trace was not public you could using the public namespace to call the original function :

class B {
    public function B() {
        // call the trace function that is defined in the public namespace
        public::trace("Hello, B!"); // output "Hello, B!"
    }

    // here the function is protected so not into the public namespace
    protected function trace(s:String):void {
        // do something else.
    }
}
假扮的天使 2024-11-26 06:17:38

“但是如果我不知道全局跟踪功能的存在怎么办?”

我认为这更多地表明您尚未在语言研究中进行尽职调查,而不是语言本身的错误。 AS3 中的顶级名称和关键字很少,我认为可以公平地说,如果您有兴趣学习一门语言,您至少应该熟悉该顶级。

"But what if I'm unaware of the existence of the global trace function?"

I'd see this more as an indication that you haven't yet done due diligence in your language research than as a fault in the language itself. There are very few top-level names and keywords in AS3, and I think it's fair to say that if you're interested in learning a language you should at least familiarize yourself with that top level.

如何视而不见 2024-11-26 06:17:38

另一种方法是更改​​名称绑定到全局标识符的位置,就像下面的包装类一样:

class B {
    public function B() {
        Globals.global_trace("Hello, B!"); // delegates to global trace()
    }
    public function trace(s:String):void {
        // do something else.
    }
}

class Globals {
    public function global_trace(...args) {
        // class B's identifiers are now irrelevant for the name lookup
        trace.apply(null, args);
    }
}

更本地化的方法是在隐藏全局符号之前重新绑定它:

private static var _trace:* = trace; // rebind global trace

public function trace(...args) {
    _trace.apply(null, args);
}

An alternative method would be to change the place where the name binding to the global identifier happens, like with the following wrapper class:

class B {
    public function B() {
        Globals.global_trace("Hello, B!"); // delegates to global trace()
    }
    public function trace(s:String):void {
        // do something else.
    }
}

class Globals {
    public function global_trace(...args) {
        // class B's identifiers are now irrelevant for the name lookup
        trace.apply(null, args);
    }
}

A more localized approach would be to rebind the global symbol before hiding it:

private static var _trace:* = trace; // rebind global trace

public function trace(...args) {
    _trace.apply(null, args);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文