我在比较Ruby字符串时注意到一些意外的行为。我将在下面写:
2.3.1 :011 > '5.6' >= '5.5'
=> true
2.3.1 :012 > '5.6' >= '5.7'
=> false
2.3.1 :013 > '5.6' >= '5.6.1'
=> false
2.3.1 :014 > '5.6' <= '5.6.1'
=> true
2.3.1 :016 > '4.6.1' <= '5.6'
=> true
2.3.1 :017 > '4.6.1' >= '5.6'
=> false
我在网上看到几个地方人们正在使用Gem::Version.new()
来比较语义版本。不过,这不是我的问题所在。谁能向我解释一下 Ruby 似乎能够在没有任何库帮助的情况下比较语义版本字符串?当我使用数字比较运算符比较两个字符串时会发生什么?
从上面的测试中,我想我可以确认它不仅仅是比较每个字符串的第一个/最后一个字符的 ascii 值。它也没有使用字符串长度作为我所期望的主要比较。
它检查字符串中每个字符的序号。当同一索引第一次出现不匹配时,它将停止。序数越高,字符越"大"。基本上,它类似于:
first_string.chars.map(&:ord) >= second_string.chars.map(&:ord)
正如评论中所指出的,这不会导致自然排序,因此人们使用 Gem::Version
:
'11' > '9' # => false
它正在比较纯字符串。
对于一个字符串的所有字符都在第二个字符串的开头找到的字符串...但是,如果第二个字符串的长度较长,则较短的字符串被视为小于。
否则,将逐个比较字符,直到一个字符串的位置"x">中的字符不等于第二个字符串的位置"x"中的字符,在这些情况下,字母数字序列中较早的字符被视为小于。
'cat' < 'caterpillar'
=> true
'cow' < 'caterpillar'
=> false
如果版本号超过一位数,您不能依靠它来为您提供语义版本的正确比较......所以
'5.10' >= '5.9'
=> false
(这不是人们所希望的(