我知道比Java更动态的语言,如Python和Ruby,通常允许您将混合类型的对象放在数组中,如下所示:
["hello", 120, ["world"]]我不明白的是,为什么你会使用这样的功能。如果我想在Java中存储异构数据,我通常会为它创建一个对象。
例如,假设一个User包含int ID和String name。在Python/Ruby/PHP中,你可以这样做:
[["John Smith", 000], ["Smith John", 001], ...]与创建一个具有ID和name属性的类User,然后拥有您的数组相比,这似乎不太安全/OO:
[<User: name="John Smith", id=000>, <User: name="Smith John", id=001>, ...]其中,这些<User ...>对象表示用户对象。
在支持它的语言中,有理由使用前者而不是后者吗?或者,使用异构数组还有更大的原因?
注:我不是在谈论包含不同对象的数组,这些对象都实现相同的接口或继承自相同的父对象,例如:
class Square extends Shape
class Triangle extends Shape
[new Square(), new Triangle()]因为,至少对程序员来说,这仍然是一个同质数组,因为您将对每个形状做相同的事情(例如,调用draw()方法),只有在两者之间共同定义的方法。
发布于 2010-12-27 01:17:39
正如katrielalex所写的:没有理由不支持异构列表。事实上,不允许它需要静态类型,我们又回到了那个古老的争论中。但让我们避免这样做,而是回答“你为什么要使用那个”部分……
老实说,它用得不多--如果我们利用你最后一段中的异常,并选择一个比Java或C#更宽松的“实现相同接口”的定义。我几乎所有的可迭代处理代码都希望所有的项目都实现一些接口。当然是这样的,否则对它的影响很小!
不要误会我的意思,这里有绝对有效的用例--很少有一个好的理由去写一个完整的类来包含一些数据(即使你添加了一些可调用的,函数式编程有时也会有帮助)。不过,字典可能是更常见的选择,而且namedtuple也非常简洁。但它们并不像你想象的那样常见,而且它们是以思考和纪律的方式使用的,而不是用于牛仔编码。
(还有,你的"User as not“示例并不是一个好的例子--因为内部列表是固定大小的,你最好使用元组,这使得它在Haskell中也是有效的(类型应该是[(String, Integer)]))
发布于 2010-12-27 01:12:18
将multimethod应用于数组可能会有一定的意义。您将策略切换到更具功能性的样式,在这种样式中,您将重点放在离散的逻辑片段(即multimethod)上,而不是离散的数据片段(即数组对象)上。
在您的形状示例中,这使您不必定义和实现Shape接口。(是的,这在这里不是什么大问题,但是如果shape是您想要扩展的几个超类之一呢?在Java中,您在这一点上是SOL。)相反,您可以实现一个智能的draw()多方法,该方法首先检查参数,然后在对象不可绘制时调度到适当的绘制功能或错误处理。
函数式风格和面向对象风格之间的比较比比皆是;这里有两个相关的问题,它们应该提供一个良好的开端:Functional programming vs Object Oriented programming和Explaining functional programming to object-oriented programmers and less technical people。
发布于 2010-12-27 02:22:27
有理由在支持它的语言中使用前者而不是后者吗?
是的,在Python中可以做到这一点有一个非常简单的原因(我假设在Ruby中也有同样的原因):
如何检查列表的异构性?
它不能直接比较类型,因为有
repr为中心,所以你也应该能够将它们放在一个列表中。根本没有办法阻止你创建一个异类列表!
,还是有更大的理由使用异构数组?
不,我想不到。正如你已经在你的问题中提到的,如果你使用一个异构的数组,你只会使事情变得更加困难。
https://stackoverflow.com/questions/4534612
复制相似问题