Condividi tramite


Modelli di struttura degli elenchi

Annotazioni

Questo articolo è una specifica delle funzionalità. La specifica funge da documento di progettazione per la funzionalità. Include le modifiche specifiche proposte, insieme alle informazioni necessarie durante la progettazione e lo sviluppo della funzionalità. Questi articoli vengono pubblicati fino a quando le modifiche specifiche proposte non vengono completate e incorporate nella specifica ECMA corrente.

Potrebbero verificarsi alcune discrepanze tra la specifica di funzionalità e l'implementazione completata. Tali differenze vengono riportate nelle note pertinenti della riunione di progettazione linguistica (LDM) .

Ulteriori dettagli sul processo di adozione delle specifiche di funzionalità nello standard del linguaggio C# sono disponibili nell'articolo sulle specifiche .

Questione prioritaria: https://github.com/dotnet/csharplang/issues/3435

Riassunto

Consente di associare una matrice o un elenco con una sequenza di modelli, array is [1, 2, 3] ad esempio una matrice integer della lunghezza tre con 1, 2, 3 rispettivamente come elementi.

Progettazione dettagliata

La sintassi del criterio viene modificata come segue:

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
  ;

Esistono due nuovi modelli:

  • Il list_pattern viene utilizzato per trovare le corrispondenze con gli elementi.
  • Un slice_pattern è consentito una sola volta e solo direttamente in un list_pattern_clause e rimuove zero o più elementi.

Compatibilità dei criteri

Un list_pattern è compatibile con qualsiasi tipo che può essere conteggiato e indicizzato , ma ha un indicizzatore accessibile che accetta come Index argomento o un indicizzatore accessibile con un singolo int parametro. Se entrambi gli indicizzatori sono presenti, il primo è preferibile.

Un slice_pattern con un sottopattern è compatibile con qualsiasi tipo conteggiabile e sezionabile, con un indicizzatore accessibile che accetta come Range argomento o in altro modo un metodo accessibile Slice con due int parametri. Se entrambi sono presenti, il primo è preferibile.

Un slice_pattern senza un sottopattern è compatibile con qualsiasi tipo compatibile con un list_pattern.

Questo set di regole è derivato dal modello dell'indicizzatore di intervalli.

Controllo della sottosezione

Il controllo della sottosumption funziona esattamente come i modelli posizionali con ITuple : i corrispondenti sottopattern vengono confrontati in base alla posizione più un nodo aggiuntivo per la lunghezza dei test.

Ad esempio, il codice seguente genera un errore perché entrambi i modelli producono lo stesso DAG:

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

Dissimile:

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

L'ordine in cui i sottopattern vengono confrontati in fase di esecuzione non è specificato e un mancato abbinamento potrebbe non tentare di abbinare tutti i sottopattern.

Data una lunghezza specifica, è possibile che due sottopattern facciano riferimento allo stesso elemento, nel qual caso viene inserito un test per questo valore nel DAG decisionale.

  • Ad esempio, [_, >0, ..] or [.., <=0, _] diventa length >= 2 && ([1] > 0 || length == 3 || [^2] <= 0) la posizione in cui il valore di lunghezza 3 implica l'altro test.
  • Viceversa, [_, >0, ..] and [.., <=0, _] diventa length >= 2 && [1] > 0 && length != 3 && [^2] <= 0 la posizione in cui il valore di lunghezza pari a 3 non consente l'altro test.

Di conseguenza, viene generato un errore per qualcosa come case [.., p]: case [p]: in fase di esecuzione, che corrisponde allo stesso elemento nel secondo caso.

Se un sottopattern di sezione corrisponde a un elenco o a un valore di lunghezza, i sottopattern vengono considerati come se fossero un sottopattern diretto dell'elenco contenitore. Ad esempio, [..[1, 2, 3]] esegue il sottosume di un modello del formato [1, 2, 3].

I presupposti seguenti vengono effettuati sui membri in uso:

  • Si presuppone che la proprietà che rende conteggiabile il tipo restituisca sempre un valore non negativo, se e solo se il tipo è indicizzabile. Ad esempio, il modello { Length: -1 } non può mai corrispondere a una matrice.
  • Il membro che rende il tipo sezionabile si presuppone un comportamento corretto, ovvero il valore restituito non è mai Null e che si tratta di una sottoslice corretta dell'elenco contenitore.

Il comportamento di un'operazione di corrispondenza dei criteri non è definito se uno dei presupposti precedenti non è presente.

Abbassamento

Un modello del modulo expr is [1, 2, 3] equivale al codice seguente:

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

Un slice_pattern agisce come un'eliminazione corretta, ovvero nessun test verrà generato per tale modello, ma influisce solo su altri nodi, vale a dire la lunghezza e l'indicizzatore. Ad esempio, un modello del modulo expr is [1, .. var s, 3] è equivalente al codice seguente (se compatibile tramite esplicito Index e Range supporto):

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

Il tipo di input per il slice_pattern è il tipo restituito del metodo o this[Range] sottostante Slice con due eccezioni: Per string e matrici string.Substring e RuntimeHelpers.GetSubArray verrà usato rispettivamente.

Domande non risolte

  1. È consigliabile supportare matrici multidimensionali? (risposta [LDM 2021-05-26]: non supportato. Se si vuole creare una versione incentrata sull'array MD generale, è consigliabile rivedere tutte le aree attualmente mancanti, non solo i modelli di elenco.
  2. Dovremmo accettare un modello generale in .. un slice_pattern? (risposta [LDM 2021-05-26]: Sì, qualsiasi criterio è consentito dopo una sezione.
  3. In questa definizione, il modello [..] verifica per expr.Length >= 0. Dovremmo omettere tale test, supponendo Length che sia sempre non negativo? (risposta [LDM 2021-05-26]: [..] non genererà un controllo lunghezza)