英文:
Why does Ruby have the "Array#<=>" but not "Array#<"?
问题
你可以像这样比较两个数组。
我想知道为什么没有像>
、<
等运算符。这是有意设计的吗?如果是的话,这方面的历史是什么?
英文:
You can compare two arrays like this.
p ([1, 2] <=> [1, 3]) < 0 # [1, 2] < [1, 3]
p ([1, 2] <=> [1, 3]) > 0 # [1, 2] > [1, 3]
p ([1, 2] <=> [1, 3]) == 0 # [1, 2] == [1, 3]
I wonder why there are no operators like >
, <
, etc. Is it an intentional design or not? If it is, what is the history on it?
答案1
得分: 1
我对原帖的意见:
> 当你将数组用作数据结构的键时,比如优先队列(heap),数组比较很有用。
在这种情况下,我更喜欢有明确的逻辑。例如:
class Key
attr_reader :array
def initialize(array)
@array = array
end
def <(other)
(array <=> other.array) < 0
end
def >(other)
(array <=> other.array) > 0
end
def ==(other)
(array <=> other.array) == 0
end
end
key1 = Key.new([1, 2])
key2 = Key.new([1, 3])
p key1 < key2
p key1 > key2
p key1 == key2
这段代码实现了数组比较的逻辑。
英文:
My five cents to OP comment:
> The array comparison is useful when you use an array as a key of the data structure, such as a priority queue(heap).
In that case I would prefer to have an explicit logic for that. For example:
class Key
attr_reader :array
def initialize(array)
@array = array
end
def <(other)
(array <=> other.array) < 0
end
def >(other)
(array <=> other.array) > 0
end
def ==(other)
(array <=> other.array) == 0
end
end
key1 = Key.new([1, 2])
key2 = Key.new([1, 3])
p key1 < key2
p key1 > key2
p key1 == key2
答案2
得分: 1
我根据Stefan提供的信息来回答我的问题。
这是Ruby的原始作者Matz故意设计的。按字典顺序比较两个数组是一个自然而有用的想法。但它们并不总是可比较的,就像这个例子。
p [1, 2] <=> [1, 'x'] # 这会返回nil,因为你不能比较2和'x'。
Matz担心提供普通的比较运算符会给人一种错误的印象,即数组总是可以比较的。但他无法完全放弃比较数组,所以提供了特殊的<=>
运算符。您可以在相关功能请求的回答中阅读他的回答:Feature#5574 - Make arrays comparable。
因此,这个设计决策是一种有主见的决策,而不是技术性的决策。在我个人看来,如果提供普通运算符并在数组不可比较时引发异常会更一致。(我是Ruby和Python的粉丝。)
英文:
I'm answering my own question based on the information provided by Stefan.
It was an intentional design by Matz, the original author of Ruby. Comparing two arrays by comparing elements in lexicographical order is a natural and useful idea. But they are not always comparable, like this example.
p [1, 2] <=> [1, 'x'] # This returns nil, because you can't compare 2 and 'x'.
Matz was concerned that providing ordinary comparison operators would give a false impression that arrays are always comparable. But he couldn't give up comparing arrays entirely and provided the special <=>
operator. You can read his answer on the related feature request at Feature#5574 - Make arrays comparable.
So the design decision was an opinionated one rather than a technical one. In my humble opinion, it would be more consistent if ordinary operators are provided and an exception is raised when arrays are not comparable. (I'm a fan of both Ruby and Python.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论