为什么#at:put: 在 SmallInteger 的 GNU Smalltalk 消息中?
在使用 GNU Smalltalk 中的 Array
类时,我很惊讶 #at:put:
消息属于类 SmallInteger
而不是Array
类(或 Array
的任何其他超类)。为什么?
While playing around with the Array
class in GNU Smalltalk, I was suprised that the #at:put:
message belongs to the class SmallInteger
instead of the class Array
(or any other super class of Array
). Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
#at:put:
是在Object
上定义的。SmallInteger
确实重新定义它以引发异常,因为它不可索引,并且任何子类也不可索引。这也有点棘手。
详细解释:
1)
SmallInteger
只是在虚拟机中转换为整数。事实上,
SmallInteger
a
在虚拟机中被转换为(a bitShift: 1) bitOr: 1
。2)
#at:put:
是一个原语,用于检查类是否可索引。可索引对象是可以发送#at:put:
、#at:
并且必须通过#new:
实例化的对象。这是拥有变量实例的方法,也是唯一的方法。 (切线:OrderedCollection
正在实例化其他中的几个可索引对象,让您多次调用#add:
并感觉长度是无限的)。3) 知道如果
#at:put:
没有在SmallIntager
类中重新定义,基元必须首先检查该对象是否是SmallInteger
code> 然后检查它是否可索引。这会给你带来一些性能损失。重新定义SmallInteger
上的#at:put:
只需删除SmallInteger
检查即可。#at:put:
is define onObject
.SmallInteger
does redefine it to throw an exception since it is not indexable and any subclass while also not be indexable.Also this is a bit tricky.
Long explanation:
1)
SmallInteger
are just translate into integer in the VM.In fact the
SmallInteger
a
is translate into(a bitShift: 1) bitOr: 1
in the VM.2)
#at:put:
is a primitive that check if the class is indexable. Indexable object are the one that can be sent#at:put:
,#at:
and have to be instantiate via#new:
. This is the way to have variable instances and it is the only way. (Tangent:OrderedCollection
is instantiating several indexable object in other to let you call#add:
multiple time and feel like the length was infinite).3) Knowing that if
#at:put:
was not redefine in theSmallIntager
class, the primitive would have to first check if the object is anSmallInteger
then check if it is indexable. This would cause you some performance penalty. And redefining the#at:put:
onSmallInteger
just remove theSmallInteger
check.