Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Notatka
Ten artykuł jest specyfikacją funkcji. Specyfikacja służy jako dokument projektowy dla funkcji. Zawiera proponowane zmiany specyfikacji wraz z informacjami wymaganymi podczas projektowania i opracowywania funkcji. Te artykuły są publikowane do momentu sfinalizowania proponowanych zmian specyfikacji i włączenia ich do obecnej specyfikacji ECMA.
Mogą wystąpić pewne rozbieżności między specyfikacją funkcji a ukończoną implementacją. Te różnice są ujęte w odpowiednich notatkach z posiedzenia dotyczącego projektowania języka (LDM).
Więcej informacji na temat procesu wdrażania specyfikacji funkcji można znaleźć w standardzie języka C# w artykule dotyczącym specyfikacji .
Problem z liderem: https://github.com/dotnet/csharplang/issues/3435
Streszczenie
Pozwala dopasować tablicę lub listę do sekwencji wzorców, np. array is [1, 2, 3] będzie pasować do tablicy całkowitej o długości trzech z elementami 1, 2, 3.
Szczegółowy projekt
Składnia wzorca jest modyfikowana w następujący sposób:
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
;
Istnieją dwa nowe wzorce:
- list_pattern służy do dopasowywania elementów.
- slice_pattern jest dozwolona tylko raz i tylko bezpośrednio w list_pattern_clause i odrzuca zero lub więcej elementów.
Zgodność wzorca
list_pattern jest zgodny z dowolnym typem, który jest zliczalny oraz indeksowalny — posiada dostępny indeksator, który przyjmuje Index jako argument, lub inny dostępny indeksator z jednym parametrem int. Jeśli oba indeksatory są obecne, preferowane jest poprzednie.
slice_pattern z podwzorcą jest zgodny z dowolnym typem, który jest zliczalny, a także fragmentowalny — ma dostępny indeksator, który przyjmuje Range jako argument lub w inny sposób dostępną metodę Slice z dwoma parametrami int. Jeśli oba są obecne, preferowane jest poprzednie.
slice_pattern bez podwzorcy jest zgodny z dowolnym typem zgodnym z list_pattern.
Ten zestaw reguł pochodzi ze wzorca indeksatora zakresu .
Sprawdzanie subsumpcji
Sprawdzanie subsumpcji działa podobnie jak wzorce pozycyjne z ITuple — odpowiednie podwzory są dopasowywane przez położenie oraz dodatkowy węzeł do testowania długości.
Na przykład następujący kod generuje błąd, ponieważ oba wzorce dają ten sam daG:
case [_, .., 1]: // expr.Length is >= 2 && expr[^1] is 1
case [.., _, 1]: // expr.Length is >= 2 && expr[^1] is 1
W odróżnieniu od
case [_, 1, ..]: // expr.Length is >= 2 && expr[1] is 1
case [.., 1, _]: // expr.Length is >= 2 && expr[^2] is 1
Kolejność dopasowywania podwzorców w czasie wykonywania jest nieokreślona, a w przypadku nieudanego dopasowania, może ono nie próbować dopasować wszystkich podwzorców.
Biorąc pod uwagę określoną długość, możliwe, że dwa podwzorcy odnoszą się do tego samego elementu, w takim przypadku test dla tej wartości zostaje wstawiony do drzewa decyzyjnego DAG.
- Na przykład
[_, >0, ..] or [.., <=0, _]staje sięlength >= 2 && ([1] > 0 || length == 3 || [^2] <= 0), gdy wartość długości 3 oznacza drugi test. - Z drugiej strony
[_, >0, ..] and [.., <=0, _]staje sięlength >= 2 && [1] > 0 && length != 3 && [^2] <= 0, gdy wartość długości 3 nie zezwala na drugi test.
W związku z tym błąd jest generowany dla czegoś takiego jak case [.., p]: case [p]:, ponieważ w czasie wykonywania dopasowujemy ten sam element w drugim przykładzie.
Jeśli podwzorce wycinka pasują do listy lub wartości długości, podwzorce są traktowane tak, jakby były bezpośrednim podwzorcami zawierającej listy. Na przykład [..[1, 2, 3]] subsumuje wzorzec o postaci [1, 2, 3].
Dla używanych członków przyjmuje się następujące założenia:
- Przyjmuje się, że właściwość sprawiająca, iż typ jest zliczalny, zawsze zwraca wartość nieujemną wtedy i tylko wtedy, gdy typ ten jest indeksowalny . Na przykład wzorzec
{ Length: -1 }nigdy nie może być zgodny z tablicą. - Element członkowski, który umożliwia, aby typ można było pociąć, jest uznawany za dobrze zachowujący się, to znaczy, że zwracana wartość nigdy nie jest zerem i że jest to prawidłowa podlista listy zawierającej.
Zachowanie operacji dopasowywania wzorca jest niezdefiniowane, jeśli którekolwiek z powyższych założeń nie zostaje spełnione.
Obniżenie
Wzorzec formularza expr is [1, 2, 3] jest odpowiednikiem następującego kodu:
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 działa jak prawidłowe odrzucenie, tzn. dla takiego wzorca nie będą generowane żadne testy, lecz będzie to wpływać tylko na inne węzły, jak długość i indeksator. Na przykład wzorzec w formacie expr is [1, .. var s, 3] jest odpowiednikiem następującego kodu (jeśli jest zgodny poprzez explicitne wsparcie Index i 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
Typ danych wejściowych dla slice_pattern jest typem zwrotnym bazowej metody this[Range] lub Slice z dwoma wyjątkami: w przypadku string i tablic zostaną użyte odpowiednio string.Substring i RuntimeHelpers.GetSubArray.
Nierozwiązane pytania
- Czy powinniśmy obsługiwać tablice wielowymiarowe? (odpowiedź [LDM 2021-05-26]: Nieobsługiwane. Jeśli chcemy utworzyć ogólną wersję skoncentrowaną na tablicy MD, chcemy ponownie przejrzeć wszystkie obszary, których obecnie brakuje, a nie tylko wzorce listy).
- Czy powinniśmy zaakceptować ogólny wzorzec po
..w slice_pattern? (odpowiedź [LDM 2021-05-26]: Tak, każdy wzorzec jest dopuszczalny po wycinku.) - Zgodnie z tą definicją wzorzec
[..]testujeexpr.Length >= 0. Czy należy pominąć taki test, zakładając, żeLengthzawsze nie jest ujemna? (odpowiedź [LDM 2021-05-26]:[..]nie będzie przeprowadzać kontroli długości)
C# feature specifications