我开始在 Smalltalk 中编码并被困在这里。我有这个二维数组:
testArr := Array new: 1.
testArr at: 1
put: ((Array new: 3)
at: 1 put: '1A';
at: 2 put: '1B';
at: 3 put: '1C';
yourself).
但是如果我想访问第一个数组的第一个元素,我应该写什么来实现它?
谢谢!
最佳答案
我很想利用你的问题和答案,并详细阐述一些属于 Smalltalk 民间传说的知识(你可能已经知道了)。
随着我们使用 Smalltalk 的进展,我们可能会注意到 Array
类在我们的模型中的作用开始减弱。这是为什么?因为需要时间来找出我们的模型将生成哪些对象;太多和太少之间的平衡是一个微妙的问题,一开始大多毫 headless 绪。
数组及其组合是方便的数据结构。然而,它们解决了组织数据的问题,但却以处理数据为代价。如果这种结构的客户端需要知道数据如何存储作为对其进行操作的先决条件,那么消息范式在语义上就变得空闲了。
让我们想象一个矩阵对象。有几种方法可以保存它们的条目:一维数组、行数组、列数组、(稀疏)非空条目的字典、三角形结构(如果矩阵已知是对称/反对的)对称/厄米特,以及更多特殊情况。当然,这种多样性对于当前的问题没有任何意义,并且无论如何,花时间考虑最通用的方法都是一个坏主意:在 Smalltalk 中,通用性是在消息上获得的,而不是在内容上获得的。存储。
无论数据的内部组织如何,我们的对象都应该始终提供独立于底层结构的协议(protocol)。回到矩阵示例,即使我们最初的组织是行数组,无论行是数组还是也用于其他目的的更复杂的向量对象,矩阵对象都应该以相同的方式工作。这意味着,在对条目 (i,j)
进行内部访问编码时,我们应该假装不知道行 i
的类,而只知道访问其 (i,j)
的消息。第 j 个元素。类似于
atRow: i column: j
| row |
row := self row: i.
^row at: j
这里我们不假设row
是一个Array
;我们只是假设它理解 at:
消息,这是我们在与行对象交谈时至少可以假设的,无论其实际性质如何。当然,只有在假设行不会像我们的类保留列集合那样动态重新创建的情况下,此代码才有效。但这没关系,否则我们只需要添加另一个类并覆盖这个类和其他一些低级消息。
无论如何,我们的想法是尽可能推迟有关内部组织的任何明确知识,以便将其限制在一些私有(private)消息中。测试我们是否应用这种良好实践的一种方法是确保没有低级代码在两个或多个方法中重复。例如,使用上面的 row:
消息将低级代码从 atRow:column:
移开,将其推迟到另一个对(理想)矩阵协议(protocol)有意义的代码.
这个例子说明了一个重要的点:要怀疑任何需要组成两个 at:
消息的代码。并且——为什么不——享受不必声明类型的美妙。
关于arrays - 如何在 Smalltalk 中访问二维数组中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60643547/