2012-04-15 39 views
0

可能重複:
Array slicing in Ruby: looking for explanation for illogical behaviour (taken from Rubykoans.com)紅寶石陣列片,不能理解這個簡單的代碼片段

我有一個簡單陣列對象:

array = [:peanut, :butter, :and, :jelly] 

其長度爲,顯然,4!

現在,看看這些語句:

array[4,0] == [] 
array[5,0] == nil 

切片從4日指數的陣列,它返回一個空數組,但是從第五元素開始,它返回零。爲什麼會發生?

+0

找到了答案,謝謝!但我不喜歡它:) – 2012-04-15 13:18:24

回答

1

slice(start, length)(這是訪問array[]時調用的方法)返回從索引start開始的長度爲length的數組。這解釋了爲什麼array[4,0]返回[]

但是,這種方法存在一個角落案例。 The Ruby documentation of slice說:

如果索引(或起始索引)超出範圍,則返回nil。

在第二個示例中,5超出了範圍array。這會導致該方法返回nil

+1

是的,但4也超出範圍。我錯了嗎? – 2012-04-15 13:07:05

1

有一秒鐘,我以爲你發現了一個錯誤,但我想我可以解釋這種行爲。您給slice的起始索引僅在之前被認爲是該索引處的元素。所以索引4被認爲是該陣列的非常結尾(就在索引4之前,恰在索引3之後)。下面的例子應該說清楚:

> [1,2,3,4][0, 3] 
# => [1, 2, 3] 
> [1,2,3,4][1, 3] 
# => [2, 3, 4] 
> [1,2,3,4][2, 3] 
# => [3, 4] 
> [1,2,3,4][3, 3] 
# => [4] 
> [1,2,3,4][4, 3] 
# => [] 
> [1,2,3,4][5, 3] 
# => nil 
1

其實,你發現「奇怪」的東西的原因應該總是在源代碼中。我隨便挑了有關代碼段從https://github.com/ruby/ruby/blob/trunk/range.c

... 
if (beg < 0) { 
beg += len; 
if (beg < 0) 
    goto out_of_range; 
} 
if (err == 0 || err == 2) { 
if (beg > len) 
    goto out_of_range; 
if (end > len) 
    end = len; 
} 
... 

這裏,如果起始索引beg比-length小,它返回超出範圍Qnil。否則,如果起始索引大於數組的長度(代碼片段中的len),則它也會返回超出範圍(Qnil)。注意這裏,它大於不大於或等於,這就是爲什麼你得到[]array[4,0](雖然4是超出範圍),但nilarray[5,0]