Bagikan melalui


Daftar pola

Nota

Artikel ini adalah spesifikasi fitur. Spesifikasi berfungsi sebagai dokumen desain untuk fitur tersebut. Ini termasuk perubahan spesifikasi yang diusulkan, bersama dengan informasi yang diperlukan selama desain dan pengembangan fitur. Artikel ini diterbitkan sampai perubahan spesifikasi yang diusulkan diselesaikan dan dimasukkan dalam spesifikasi ECMA saat ini.

Mungkin ada beberapa perbedaan antara spesifikasi fitur dan implementasi yang selesai. Perbedaan tersebut dicatat dalam catatan rapat desain bahasa (LDM) yang terkait.

Anda dapat mempelajari lebih lanjut tentang proses untuk mengadopsi speklet fitur ke dalam standar bahasa C# dalam artikel tentang spesifikasi .

Masalah utama: https://github.com/dotnet/csharplang/issues/3435

Ringkasan

Memungkinkan Anda mencocokkan array atau daftar dengan urutan pola misalnya array is [1, 2, 3] akan cocok dengan array bilangan bulat dengan panjang tiga dengan masing-masing 1, 2, 3 sebagai elemennya.

Desain terperinci

Sintaks pola dimodifikasi sebagai berikut:

list_pattern_clause
  : '[' (pattern (',' pattern)* ','?)? ']'
  ;

list_pattern
  : list_pattern_clause simple_designation?
  ;

slice_pattern
  : '..' pattern?
  ;

primary_pattern
  : list_pattern
  | slice_pattern
  | // all of the pattern forms previously defined
  ;

Ada dua pola baru:

  • list_pattern digunakan untuk mencocokkan elemen.
  • slice_pattern hanya diizinkan sekali dan hanya langsung dalam list_pattern_clause dan membuang elemen nol atau lebih.

Kompatibilitas pola

list_pattern kompatibel dengan jenis apa pun yang dapat dihitung serta yang dapat diindeks — memiliki pengindeks yang dapat diakses yang mengambil Index sebagai argumen atau pengindeks yang dapat diakses dengan satu parameter int. Jika kedua pengindeks ada, yang pertama lebih disukai.

slice_pattern dengan subpattern kompatibel dengan jenis apa pun yang yang dapat dihitung serta yang dapat dipotong — memiliki pengindeks yang dapat diakses yang mengambil Range sebagai argumen atau metode Slice yang dapat diakses dengan dua parameter int. Jika keduanya ada, yang pertama lebih disukai.

slice_pattern tanpa subpattern kompatibel dengan jenis apa pun yang kompatibel dengan list_pattern.

Seperangkat aturan ini berasal dari pola pengindeks rentang .

Pemeriksaan subsumsi

Pemeriksaan subsumption berfungsi seperti pola posisi dengan ITuple - subpola yang sesuai dicocokkan berdasarkan posisi ditambah node tambahan untuk menguji panjang.

Misalnya, kode berikut menghasilkan kesalahan karena kedua pola menghasilkan DAG yang sama:

case [_, .., 1]: // expr.Length is >= 2 && expr[^1] is 1
case [.., _, 1]: // expr.Length is >= 2 && expr[^1] is 1

Tidak seperti:

case [_, 1, ..]: // expr.Length is >= 2 && expr[1] is 1
case [.., 1, _]: // expr.Length is >= 2 && expr[^2] is 1

Urutan di mana subpola cocok saat runtime tidak ditentukan, dan kecocokan yang gagal mungkin tidak mencoba mencocokkan semua subpola.

Mengingat panjang tertentu, ada kemungkinan bahwa dua subpattern merujuk ke elemen yang sama, dalam hal ini pengujian untuk nilai ini dimasukkan ke dalam DAG keputusan.

  • Misalnya, [_, >0, ..] or [.., <=0, _] menjadi length >= 2 && ([1] > 0 || length == 3 || [^2] <= 0) di mana nilai panjang 3 menyiratkan pengujian lainnya.
  • Sebaliknya, [_, >0, ..] and [.., <=0, _] menjadi length >= 2 && [1] > 0 && length != 3 && [^2] <= 0 di mana nilai panjang 3 melarang pengujian lainnya.

Akibatnya, kesalahan dihasilkan pada sesuatu seperti case [.., p]: case [p]: karena pada runtime, kami mencocokkan elemen yang sama dalam kasus kedua.

Jika subpola irisan cocok dengan daftar atau nilai panjang, subpola diperlakukan seolah-olah subpola langsung dari daftar yang mengandungnya. Misalnya, [..[1, 2, 3]] mencakup pola berbentuk [1, 2, 3].

Asumsi berikut dibuat pada anggota yang digunakan:

  • Properti yang membuat jenis dapat dihitung diasumsikan selalu mengembalikan nilai non-negatif, jika dan hanya jika jenis dapat diindeks. Misalnya, pola { Length: -1 } tidak pernah dapat mencocokkan array.
  • Anggota yang membuat jenis dapat dipotong diasumsikan berperilaku baik, yaitu, nilai pengembaliannya tidak pernah null dan itu adalah sub-irisan yang tepat dari daftar yang memuat.

Perilaku operasi pencocokan pola tidak ditentukan jika salah satu asumsi di atas tidak berlaku.

Menurunkan

Pola formulir expr is [1, 2, 3] setara dengan kode berikut:

expr.Length is 3
&& expr[new Index(0, fromEnd: false)] is 1
&& expr[new Index(1, fromEnd: false)] is 2
&& expr[new Index(2, fromEnd: false)] is 3

slice_pattern bertindak seperti pengabaian yang semestinya, yaitu tidak ada pengujian yang akan dikeluarkan untuk pola tersebut, melainkan hanya memengaruhi node lain, yaitu panjang dan pengindeksan. Misalnya, pola formulir expr is [1, .. var s, 3] setara dengan kode berikut (jika kompatibel melalui Index eksplisit dan dukungan Range):

expr.Length is >= 2
&& expr[new Index(0, fromEnd: false)] is 1
&& expr[new Range(new Index(1, fromEnd: false), new Index(1, fromEnd: true))] is var s
&& expr[new Index(1, fromEnd: true)] is 3

Jenis input untuk slice_pattern adalah jenis pengembalian dari metode this[Range] atau Slice yang mendasar dengan dua pengecualian: Untuk string dan array, masing-masing string.Substring dan RuntimeHelpers.GetSubArray akan digunakan.

Pertanyaan yang belum terselesaikan

  1. Haruskah kita mendukung array multi-dimensi? (jawaban [LDM 2021-05-26]: Tidak didukung. Jika kita ingin membuat rilis yang berfokus pada array MD umum, kita harus meninjau kembali semua area yang saat ini kurang, bukan hanya pola-pola dalam daftar.)
  2. Haruskah kita menerima pola umum mengikuti .. dalam slice_pattern? (jawaban [LDM 2021-05-26]: Ya, pola apa pun diizinkan setelah irisan.)
  3. Menurut definisi ini, pola [..] digunakan untuk menguji expr.Length >= 0. Haruskah kita menghilangkan tes seperti itu, dengan asumsi Length selalu non-negatif? (jawaban [LDM 2021-05-26]: [..] tidak akan mengeluarkan pemeriksaan Panjang)