不可变集合 Actionscript 3

发布于 2024-07-14 12:22:11 字数 410 浏览 9 评论 0原文

我最近一直在尝试在 AS3 中实现一些干净的编码实践。 其中之一是不泄露包含对象中对数组的引用。 要点是我控制一个类的添加和删除,并且数组的所有其他用户接收只读版本。

目前,只读版本是我编写的 ArrayIterator 类,它实现了典型的 Iterator 接口(hasNext、getNext)。 它还扩展了 Proxy,因此可以像数组一样在 foreach 循环中使用。

所以我的问题是这不应该是许多语言的基本特征吗? 能够传递引用以只读集合视图吗?

另外,现在 AS3 中的集合以 Vector 类的形式改进了类型安全性,当我将一个 Vector 包装在 VectorIterator 中时,我会因为以下原因而丢失输入:不变性。 有没有办法在 AS3 中实现不变性和类型这两个愿望?

I've been trying lately to implement some clean coding practices in AS3. One of these has been to not give away references to Arrays from a containing object. The point being that I control addition and removal from one Class and all other users of the Array receive read only version.

At the moment that read only version is a ArrayIterator class I wrote, which implements a typical Iterator interface (hasNext, getNext). It also extends Proxy so it can be used in for each loops just as a Array can.

So my question is should this not be a fundamental feature of many languages? The ability to pass around references to read only views of collections?

Also now that there is improved type safety for collections in AS3 , in the form of the Vector class, when I wrap a a Vector in a VectorIterator I lose typing for the sake of immutability. Is there a way to implement the two desires, immutability and typing in AS3?

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

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

发布评论

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

评论(5

明月松间行 2024-07-21 12:22:11

看来使用 Iterator 模式是最好的方法目前在 AS3 中用于在系统中传递集合,同时保证它不会被修改。

我使用的 IIterator 接口是基于 Java 迭代器,但我没有实现remove()方法,因为这在Java社区中被许多人认为是一个设计错误,因为它允许用户删除数组元素。 下面是我的 IIterator 实现:

 public interface IIterator
 {
     function get hasNext():Boolean
     function next():*
 }

然后由 ArrayIterator、VectorIterator 等类实现。

为了方便起见,我还在具体的 Iterator 类上扩展了 Proxy,并为for-each 在 AS3 中通过重写 nextNameIndex()nextValue() 方法进行循环。 这意味着在使用我的IIterator时,通常使用数组的代码不需要更改。

var array:Array = ["one", "two", "three"]

for each (var eachNumber:String in array)
{
    trace(eachNumber)
}

var iterator:IIterator = new ArrayIterator(array)

for each (var eachNumber:String in iterator)
{
    trace(eachNumber)
}

唯一的问题是...用户无法查看 IIterator 接口并知道他们可以使用 for-each 循环来迭代集合。 他们必须查看 ArrayIterator 的实现才能看到这一点。

It seems that using an Iterator pattern is the best way currently in AS3 to pass a collection around a system, while guaranteeing that it will not be modified.

The IIterator interface I use is modeled on the Java Iterator, but I do not implement the remove() method, as this is considered a design mistake by many in the Java community, due to it allowing the user to remove array elements. Below is my IIterator implemention:

 public interface IIterator
 {
     function get hasNext():Boolean
     function next():*
 }

This is then implemented by classes such as ArrayIterator, VectorIterator etc.

For convenience I also extend Proxy on my concrete Iterator classes, and provide support for the for-each loops in AS3 by overriding the nextNameIndex() and nextValue() methods. This means code that typically used Arrays does not need to change when using my IIterator.

var array:Array = ["one", "two", "three"]

for each (var eachNumber:String in array)
{
    trace(eachNumber)
}

var iterator:IIterator = new ArrayIterator(array)

for each (var eachNumber:String in iterator)
{
    trace(eachNumber)
}

Only problem is... there is no way for the user to look at the IIterator interface and know that they can use a for-each loop to iterate over the collection. They would have to look at the implementation of ArrayIterator to see this.

可是我不能没有你 2024-07-21 12:22:11

有些人会认为,您可以将此类模式实现为库,这一事实是反对向语言本身添加功能的论据(例如,C++ 语言设计者通常这么说)。

Some would argue that the fact that you can implement such patterns as libraries is an argument against adding features to the language itself (for example, the C++ language designers typically say that).

紙鸢 2024-07-21 12:22:11

您是否通过代理对象获得了您想要的不变性? 请注意,您可以让 VectorIterator 构造函数采用强制的 Class 参数。 诚然,目前这对设计师来说并不友好,但我们希望未来情况会有所改善。

Do you have the immutability you want via the proxy object or not? Note, you can have the VectorIterator constructor take a mandatory Class parameter. Admittedly this is not designer friendly at the moment, but lets hope things will improve in the future.

拍不死你 2024-07-21 12:22:11

我为 AS3 创建了一个小型的不可变集合类库,其中包括一个类型化的有序列表,听起来它可以满足您的需求。 请参阅此博文了解细节。

I have created a small library of immutable collection classes for AS3, including a typed ordered list, which sounds like it would meet your needs. See this blog post for details.

我不吻晚风 2024-07-21 12:22:11

为了实现这一目标,我所做的就是让维护列表的类仅通过 slice()。 例如,我的游戏引擎有一个类 Scene ,它维护已添加到其中的所有 Beings 的列表。 然后,该列表将作为副本公开,如下所示:(

public function get beings():Vector.<Being>
{
    return _beings.slice();
}

抱歉,要恢复旧线程,我在寻找方法来准确实现 Brian 的答案所涵盖的内容时遇到了这个问题,并认为我会在此事上投入 2 美分)。

Something I do to achieve this is to have the class that maintains the list only return a copy of that list in a getter via slice(). As an example, my game engine has a class Scene which maintains a list of all the Beings that have been added to it. That list is then exposed as a copy like so:

public function get beings():Vector.<Being>
{
    return _beings.slice();
}

(Sorry to revive an old thread, I came across this while looking for ways to implement exactly what Brian's answer covers and thought I would throw my 2 cents in on the matter).

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