我发现加里·赖特(Gary Wright)的解释也很有帮助。
http://www.ruby-forum.com/topic/1393096#990065
Gary Wright的答案是-
http://www.ruby-doc.org/core/classes/Array.html
这些文档当然可以更加清晰,但是实际行为是自洽的且有用的。注意:我假设使用1.9.X版本的String。
可以通过以下方式考虑编号:
-4 -3 -2 -1 <-- numbering for single argument indexing
0 1 2 3
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
0 1 2 3 4 <-- numbering for two argument indexing or start of range
-4 -3 -2 -1
常见的(也是可以理解的)错误也是假设单个参数索引的语义与两个参数场景(或范围)中第一个参数的语义相同
。它们在实践中不是一回事,文档也不反映这一点。该错误肯定在文档中,而不是在实现中:
单个参数:索引表示字符串中单个字符的位置。结果要么是在索引中找到的单个字符串,要么是nil,因为给定索引中没有字符。
s = ""
s[0] # nil because no character at that position
s = "abcd"
s[0] # "a"
s[-4] # "a"
s[-5] # nil, no characters before the first one
两个整数参数:参数标识要提取或替换的字符串的一部分。特别是,还可以识别字符串的零宽度部分,以便可以在字符串前面或结尾的现有字符之前或之后插入文本。在这种情况下,第一个参数并不能识别一个字符的位置,而是标识如上所示的图中的字符之间的空间。第二个参数是长度,可以为0。
s = "abcd" # each example below assumes s is reset to "abcd"
To insert text before 'a': s[0,0] = "X" # "Xabcd"
To insert text after 'd': s[4,0] = "Z" # "abcdZ"
To replace first two characters: s[0,2] = "AB" # "ABcd"
To replace last two characters: s[-2,2] = "CD" # "abCD"
To replace middle two characters: s[1..3] = "XX" # "aXXd"
范围的行为非常有趣。当提供了两个参数时,起点与第一个参数相同(如上所述),但是范围的终点可以是像使用单索引一样的“字符位置”,也可以像是使用两个整数参数那样是“边缘位置”。区别取决于是使用双点范围还是三点范围:
s = "abcd"
s[1..1] # "b"
s[1..1] = "X" # "aXcd"
s[1...1] # ""
s[1...1] = "X" # "aXbcd", the range specifies a zero-width portion of
the string
s[1..3] # "bcd"
s[1..3] = "X" # "aX", positions 1, 2, and 3 are replaced.
s[1...3] # "bc"
s[1...3] = "X" # "aXd", positions 1, 2, but not quite 3 are replaced.
如果回头看这些示例并坚持使用双索引或范围索引示例的单索引语义,您会感到困惑。您必须使用我在ASCII图中显示的备用编号来对实际行为进行建模。