ทำไมดัชนีผู้ประกอบการหมวกใหม่ไม่ได้จากคุณสมบัติการแบ่งอาร์เรย์ C # 8 เริ่มต้นที่ 0


156

C # 8.0 แนะนำวิธีการที่สะดวกในการอาร์เรย์ชิ้น - เห็นอย่างเป็นทางการ C # 8.0 blogpost

ไวยากรณ์ในการเข้าถึงองค์ประกอบสุดท้ายของอาร์เรย์คือ

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

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

ฉันสงสัยว่าทำไมการสร้างดัชนีสำหรับการเข้าถึงองค์ประกอบย้อนหลังเริ่มต้นที่ 1 แทนที่จะเป็น 0 มีเหตุผลทางเทคนิคสำหรับสิ่งนี้หรือไม่?


11
โปรดทราบว่าช่วง C ++ นั้นก็เช่น[beginInclusive, endExclusive)กัน มันเป็นเรื่องธรรมดา
bommelding

3
@Sinatr: ขึ้นอยู่กับการโพสต์บล็อกนั้นไวยากรณ์ที่จะคืนค่าทุกอย่างจะเป็นvalue[0..^0]เพราะดัชนีสิ้นสุดนั้นเป็นเอกสิทธิ์ (ซึ่งเป็นภาษาอื่น ๆ ด้วยเช่นกัน นอกจากนี้สะดวกvalue[^i..^0]จะให้iรายการสุดท้าย
BlueRaja - Danny Pflughoeft

1
@bommelding: C ++ rbegin()ค่อนข้างไม่เห็นด้วยกับความคิดนั้น - รายการแรกที่อยู่นอกขอบเขตนั้นไม่ใช่แบบปลายด้านหนึ่ง ;-)
DevSolar

1
โอ้เยี่ยมเลยนี่ดูเหมือนกับการสร้างดัชนีเชิงลบในไพ ธ อน:value[-1] # 13
cs95

1
@coldspeed และใน Ruby เหมือนกับ Python ฉันเดาว่าพวกเขาทั้งคู่ยืมอนุสัญญานี้จาก Perl
Wayne Conrad

คำตอบ:


170

คำตอบอย่างเป็นทางการ

เพื่อความชัดเจนยิ่งขึ้นต่อไปนี้เป็นความคิดเห็นจากMads Torgersenอธิบายการตัดสินใจออกแบบนี้จากบล็อกโพสต์ C # 8 :

เราตัดสินใจที่จะติดตาม Python เมื่อพูดถึงการคำนวณตั้งแต่ต้นจนจบ 0 กำหนดองค์ประกอบแรก (เช่นเคย) และ  ^0 องค์ประกอบ "length'th" นั่นคือองค์ประกอบหนึ่งที่ถูกต้องในตอนท้าย ด้วยวิธีนี้คุณจะได้รับความสัมพันธ์อย่างง่าย ๆ ที่ตำแหน่งขององค์ประกอบจากจุดเริ่มต้นบวกกับตำแหน่งจากจุดสิ้นสุดเท่ากับความยาว x ใน ^x  คือสิ่งที่คุณจะได้หักออกจากความยาวถ้าคุณต้องการทำด้วยตัวคุณเองคณิตศาสตร์

ทำไมไม่ใช้เครื่องหมายลบ ( -) แทน^โอเปอเรเตอร์hat ( ) ใหม่ สิ่งนี้เกี่ยวข้องกับช่วงเป็นหลัก อีกครั้งในการรักษาด้วย Python และอุตสาหกรรมส่วนใหญ่เราต้องการให้ช่วงของเรานั้นครอบคลุมตั้งแต่เริ่มต้นโดยเฉพาะในตอนท้าย ดัชนีที่คุณส่งผ่านเพื่อบอกว่าช่วงควรไปจนสุดคืออะไร? ใน C # คำตอบนั้นง่าย: x..^0ไปจาก  x ท้ายที่สุด ใน Python ไม่มีดัชนีที่ชัดเจนที่คุณสามารถให้: -0ใช้งานไม่ได้เพราะมันเท่ากับ0องค์ประกอบแรก! ดังนั้นใน Python คุณต้องปล่อยให้ดัชนีสิ้นสุดสมบูรณ์เพื่อแสดงช่วงที่ไปยังจุดสิ้นสุด: x... หากคำนวณช่วงท้ายของช่วงเวลานั้นคุณต้องจำไว้ว่าต้องใช้ตรรกะพิเศษในกรณีที่เกิด0ขึ้น เช่นเดียวกับในx..-yที่ไหนy0ถูกคำนวณและออกมา นี่คือความรำคาญทั่วไปและแหล่งที่มาของข้อบกพร่อง

สุดท้ายโปรดทราบว่าดัชนีและช่วงเป็นประเภทชั้นหนึ่งใน. NET / C # พฤติกรรมของพวกเขาไม่ได้เชื่อมโยงกับสิ่งที่พวกเขานำไปใช้หรือแม้กระทั่งที่จะใช้ในตัวทำดัชนี คุณทั้งหมดสามารถกำหนดดัชนีของคุณเองที่ใช้ดัชนีและอีกคนหนึ่งที่ใช้เวลาRange- และเรากำลังจะเพิ่ม indexers Spanดังกล่าวไปเช่น แต่คุณสามารถมีวิธีที่ใช้ช่วงเช่น

คำตอบของฉัน

ฉันคิดว่านี่คือการจับคู่ไวยากรณ์คลาสสิกที่เราคุ้นเคย:

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

หากใช้เป็น 0 จะทำให้เกิดความสับสนเมื่อมีการใช้ไวยากรณ์ทั้งสองแบบเคียงข้างกัน วิธีนี้มันมีภาระการรับรู้ต่ำกว่า

ภาษาอื่นเช่น Python ก็ใช้หลักการเดียวกัน


13
การแก้ไขเล็กน้อยในการแสดงความคิดเห็น Mads: คุณไม่จำเป็นต้องออกจากดัชนีสิ้นสุดในไพ ธ อนโดยสมบูรณ์ คุณสามารถใช้ในสถานที่ของตัวเลข:None [0,1,2,3,4][2:None] == [2,3,4]แต่ใช่คุณไม่สามารถใช้จำนวนเต็มเป็นดัชนีสิ้นสุด (โดยไม่คำนวณความยาวอย่างชัดเจน)
Giacomo Alzetta

4
รอ .. เกิดx..อะไรขึ้น ดูดีและฉันไม่เคยมีปัญหากับ[3:]ไวยากรณ์ของหลาม
mowwwalker

8
@mowwwalker - นั่นไม่ได้ครอบคลุมอยู่ในใบเสนอราคาแล้ว? "ดังนั้นใน Python ... หากคำนวณช่วงท้ายคุณจะต้องจำไว้ว่าต้องมีตรรกะพิเศษในกรณีที่มันออกมาเป็น 0"
Damien_The_Unbeliever

3
@mowwwalker Mads ความคิดเห็นเกี่ยวกับกรณีที่คุณไม่ทราบว่าค่าดัชนีจะเป็นอย่างไรเพราะมันคำนวณในทางใดทางหนึ่ง พวกเขากำลังพูดว่าในกรณีที่คุณต้องการคำนวณendIndexเป็นดัชนีลบ (เช่นดัชนีจากจุดสิ้นสุด) คุณจะมีความไม่ต่อเนื่องระหว่างจำนวนลบและบวกเพราะ0จะไม่ทำงานในวิธีที่ถูกต้องในกรณีนั้น ดังที่ฉันได้ชี้ให้เห็นว่าคุณต้องแทนที่0ด้วยNoneสิ่งนั้น ซึ่งหมายความว่ารหัสของคุณควรมีลักษณะseq[startIndex:endIndex or None]เช่น or Noneควรถูกมองข้ามถ้าendIndexคาดว่าจะเป็นบวก
Giacomo Alzetta

5
มันเป็นการดีที่จะเห็นว่าพวกเขาไม่ได้ทำซ้ำความผิดพลาดของงูใหญ่กับสิ่ง -0 การจัดการกรณีพิเศษนั้นเป็นเรื่องยุ่งยากและง่ายเกินไปที่จะลืม
user2357112 รองรับ Monica
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.