C # 8 dizi dilimleme özelliğindeki yeni hat operatörü dizini neden 0'da başlamıyor?


156

C # 8.0 dizileri dilimlemek için uygun bir yol sunar - bkz. Resmi C # 8.0 blog yazısı .

Bir dizinin son öğesine erişmek için sözdizimi şöyledir:

int value[] = { 10, 11, 12, 13 };

int a = value[^1]; // 13
int b = value[^2]; // 12

Öğelere geriye doğru erişme endekslemesinin neden 0 yerine 1'de başladığını merak ediyorum? Bunun teknik bir nedeni var mı?


11
C ++ aralıklarının da olduğunu unutmayın [beginInclusive, endExclusive). Bu ortak bir sözleşmedir.
13'te bombalanıyor

3
@Sinatr: Bu blog gönderisine dayanarak, her şey döndürecek sözdizimi value[0..^0], bitiş dizini özel olduğundan (diğer birçok dilde de çalışır) olacaktır. Ayrıca, rahatça, value[^i..^0]size son iöğeleri verecektir .
BlueRaja - Danny Pflughoeft

1
@bommelding: C ++ rbegin()bu görüşe biraz katılmıyor - bu aralıktaki ilk öğe de sonun ötesinde değil. ;-)
DevSolar

1
Oh güzel, bu python negatif indeksleme eşdeğer gibi görünüyor:value[-1] # 13
cs95

1
@coldspeed Ve Ruby'de Python ile aynı. Sanırım ikisi de bu sözleşmeyi Perl'den ödünç aldılar.
Wayne Conrad

Yanıtlar:


170

Resmi cevap

Daha iyi görünürlük için, Mads Torgersen'den C # 8 blog gönderisinden bu tasarım kararını açıklayan bir yorum :

Başlangıçtan ve sondan aritmetik konusunda Python'u takip etmeye karar verdik. 0 ilk elemanı (her zamanki gibi) ve  ^0 “uzunluk” elemanını, yani sondan bir sonraki elemanı belirtir. Bu şekilde, bir öğenin başından itibaren konumunun ve sondan konumunun uzunluğa eşit olduğu basit bir ilişki elde edersiniz. x içinde  ^x hesabı sen kendin yapmış olsaydı sen uzunluğundan çıkarılır olurdu budur.

Neden -yeni hat ( ^) operatörü yerine eksi ( ) kullanılmıyor ? Bu öncelikle aralıklarla ilgilidir. Yine Python ve endüstrinin çoğuna uygun olarak, aralıklarımızın başlangıçta kapsayıcı olmasını ve sonunda özel olmasını istiyoruz. Bir aralığın sonuna kadar gitmesi gerektiğini söylemek için geçtiğiniz dizin nedir? C # 'da cevap basit:  sonuna x..^0kadar gider  x. Python'da verebileceğiniz açık bir dizin yoktur: ilk öğeye -0eşit olduğu için çalışmaz 0! Yani Python, sonuna kadar giden bir dizi ifade etmek tamamen bitiş dizinini kapalı ayrılmak zorunda: x... Aralığın sonu hesaplanırsa, ortaya çıkması durumunda özel mantığa sahip olduğunuzu hatırlamanız gerekir 0. Olduğu gibi x..-y, neredeyhesaplandı ve çıktı 0. Bu yaygın bir sıkıntı ve hata kaynağıdır.

Son olarak, dizinlerin ve aralıkların .NET / C # içindeki birinci sınıf türler olduğunu unutmayın. Davranışları uygulandıkları şeye bağlı değildir, hatta bir indeksleyicide bile kullanılamaz. Dizin'i alan kendi dizinleyicinizi ve bunu alan başka bir dizininizi tamamen tanımlayabilirsiniz. Bu Rangetür dizinleyicileri örn  Span. Ancak, örneğin aralık alan yöntemler de kullanabilirsiniz.

Cevabım

Bunun alışkın olduğumuz klasik sözdizimiyle eşleştiğini düşünüyorum:

value[^1] == value[value.Length - 1]

Eğer 0 kullanılırsa, iki sözdizimi yan yana kullanıldığında kafa karıştırıcı olurdu. Bu şekilde daha düşük bilişsel yüke sahiptir.

Python gibi diğer diller de aynı kuralları kullanır.


13
Mads yorumunda küçük düzeltme: son endeksi python'da tamamen bırakmak zorunda değilsiniz . Sen kullanabilirsiniz Nonebirtakım yerine: [0,1,2,3,4][2:None] == [2,3,4]. Ancak, evet, bir tamsayıyı son dizin olarak kullanamazsınız (uzunluğu açıkça hesaplamadan).
Giacomo Alzetta

4
Bekle .. sorun x..nedir? Bu iyi görünüyor ve python [3:]sözdizimi ile hiç sorun yaşamadım .
mowwwalker

8
@mowwwalker - bu teklifte zaten yer almıyor mu? "Yani Python ... Eğer aralığın sonu hesaplanırsa, o zaman 0 ortaya
çıkarsa

3
@mowwwalker Mads yorumu, bir şekilde hesaplandığı için dizin değerinin ne olacağını bilmediğiniz durumlar hakkındaydı. endIndexNegatif bir indeks (yani sondan indeks) olarak hesaplamak istediğinizde, negatif ve pozitif sayılar arasında bir süreksizliğe sahip olacağınızı söylüyorlar çünkü 0bu durumda doğru şekilde çalışmayacaklar. Ben işaret ettiğine göre değiştirmek zorunda 0tarafından Nonebunun için. Bu, kodunuzun seq[startIndex:endIndex or None]örneğin görünmesi gerektiği anlamına gelir . or NoneEğer ihmal edilmelidir endIndexolumlu olması bekleniyor.
Giacomo Alzetta

5
Python'un hatasını -0 şeyle tekrar etmediklerini görmek güzel. Bu özel durumu ele almak büyük bir güçlük ve unutulması çok kolay.
user2357112 Monica
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.