生成不可变的循环数据结构

发布于 2024-09-29 12:54:27 字数 315 浏览 8 评论 0原文

假设我有这个简单的类:

public class Pair {
    public readonly object first;
    public readonly object second;

    public Pair(object first, object second) {
        this.first = first;
        this.second = second;
    }
}

不可能生成成对的循环图。

您将如何创建一个类似的类,它仍然是不可变的,但可以以某种方式用于生成循环图?

Suppose I have this simple class:

public class Pair {
    public readonly object first;
    public readonly object second;

    public Pair(object first, object second) {
        this.first = first;
        this.second = second;
    }
}

It would be impossible to generate a cyclic graph of pairs.

How would you create a similar class, that is still immutable, but can be used somehow to generate cyclic graphs?

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

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

发布评论

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

评论(3

过期情话 2024-10-06 12:54:27

表示图结构的方法有无数种。一种这样的方法是使用矩阵。每行和每列都由顶点索引,矩阵中的每个单元代表一条有向(可能是加权)边。一个简单的循环图,其中 0 没有连接边,1 有连接边,就像这样:

| 0 1 |
| 1 0 |

与许多不可变结构一样,构造它们的方式是根据给定矩阵的所需关系返回新结构。例如,如果我们想采用上面的图并将第一个顶点上的边添加回其自身,则表示该图的矩阵就是正义的。

| 1 0 |
| 0 0 |

并将其与其他矩阵结合起来,我们只需将它们加在一起即可。

| 0 1 |  +  | 1 0 |  ==  | 1 1 |
| 1 0 |     | 0 0 |      | 1 0 |

当然,表示矩阵的方法有很多种,对速度、空间和某些其他操作有不同的权衡,但这是另一个问题了。

There are zillions of ways to represent graph structures. One such way is with a matrix. each row and column is indexed by the vertex, and each cell in the matrix represents a directed (possibly weighted) edge. A simple, cyclic graph, with 0's as no connecting edge and 1 with a connecting edge would just be like so:

| 0 1 |
| 1 0 |

As with many immutable structures, the way you construct them is by returning new structures based on the desired relationship of given matrices. for instance, if we wanted to take the above graph and add an edge on the first vertex back onto itself, the matrix representing that is just.

| 1 0 |
| 0 0 |

and to combine that with the other matrix, we just add them together.

| 0 1 |  +  | 1 0 |  ==  | 1 1 |
| 1 0 |     | 0 0 |      | 1 0 |

Of course, there are many ways to represent matrices, with different tradeoffs for speed, space, and certain other operations, but that's a different question.

呢古 2024-10-06 12:54:27

我认为对于您提出的类型的严格不可变类来说这是不可能的。我唯一能想到的就是添加一个带有设置器的属性,该设置器检查字段是否为空,如果为空则允许对其进行设置。通过这种方式,您可以将第一个对象中的 first 字段保留为 null,并且在创建循环中的最后一个对象后,适当地设置该字段以关闭循环。一旦设置,它就不再为空,并且设置器将不再允许更改它。当然,该字段仍然可以通过类内部的代码进行更改,但从外部来看它基本上是不可变的。

像这样(C#):

public class Pair {
    private object first;
    private object second;

    public Pair(object first, object second) {
        this.first = first;
        this.second = second;
    }

    public object First {
        get { return first; }
        set 
        {
            if (first == null)
            {
                first = value;
            }
        }
    }

    // and a similar property for second
}

I don't think this is possible with a strictly immutable class of the type you proposed. The only thing I can think of is to add a property with a setter that check whether or not a field is null, and allows it to be set if it is. In this way you could leave the first field in the first object null, and once you've created the last object in the cycle set that field appropriately to close the loop. Once it's set, it is no longer null, and the setter would no longer allow it to be changed. It would still be possible for the field to be changed by code internal to the class, of course, but it would be essentially immutable from the outside.

Something like this (C#):

public class Pair {
    private object first;
    private object second;

    public Pair(object first, object second) {
        this.first = first;
        this.second = second;
    }

    public object First {
        get { return first; }
        set 
        {
            if (first == null)
            {
                first = value;
            }
        }
    }

    // and a similar property for second
}
羁客 2024-10-06 12:54:27

我会采用函数式方法,将延续传递给 ctor。或者,它可以采用一系列相似的元素(将 IEnumerable 视为参数)。

I would take a functional approach, passing a continuation into the ctor. Alternately, it could take a sequence of similar elements instead (think IEnumerable as an argument).

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