5

如果您有 Array 的子类 X,则doingX#to_a返回一个数组对象,而doingX#to_ary返回一个x 对象。

虽然我理解这to_a意味着“我可以变成一个数组”,而to_ary意味着“我的行为就像一个数组”,但我不明白为什么前者实现了类的改变而后者没有。

to_a此外,根据 Liskov 替换原则,返回 Array 的子类是否足够?

4

2 回答 2

3

“因为这就是它的定义方式”足够了吗?

to_a

退货self。如果在 的子类上调用Array,则将接收者转换为Array对象。

to_ary

退货self

可能不是,所以我们在这里进入兔子洞。

除了文档明确指出它就是这样的事实之外,推理可能只有 Matz 等人才能真正回答。

尽管似乎to_ary在发生隐式类型转换时使用了它。它对隐式转换的使用似乎也反映在此功能请求中。换句话说,如果一个对象响应to_ary,那么它应该被视为一个Array,并且它在内部以这种方式使用。因此to_a,当您(明确地)想要一个Array而不是某个子类时。

是的,返回一个子类仍然会满足 LSP(假设子类不决定从根本上改变Array它不会的行为),但该原则仅说明一个子类可以替换它的基类,而不是它需要是。不过,无论如何,我不确定这是否重要,因为您正在调用to_a您的明确要求不同的对象(与上面有关隐式转换的推理一起使用),因此您说您不想要替代品对象类型。

于 2012-04-17T02:45:33.860 回答
2

As a general rule, the implicit conversions are automatically called by the interpreter, and they are intended to only convert things that are very much like the type that was required but not found.

The explicit conversions, however, can be called on disparate types as long as there is some way to get from point a to point b, even if that involves some sort of polar route or a detour.

So you simply have more freedom for a leap with to_a, but I agree that it seems like X should be good enough.

于 2012-04-17T04:31:00.880 回答