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.
Dopasowanie wzorca
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ą przechwytywane w odpowiednich spotkania projektowego 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 mistrzem: https://github.com/dotnet/csharplang/issues/8640
Streszczenie
Zezwalaj na dopasowywanie wzorca Span<char> i ReadOnlySpan<char> w ciągu stałym.
Motywacja
Ze względu na wydajność, w wielu scenariuszach preferowane jest używanie Span<char> i ReadOnlySpan<char> zamiast ciągów. Aby umożliwić korzystanie z ReadOnlySpan<char> zamiast string, platforma dodała wiele nowych interfejsów API.
Typową operacją na ciągach jest użycie przełącznika do testowania, czy jest to określona wartość, a kompilator optymalizuje taki przełącznik. Jednak obecnie nie ma możliwości wykonania tego samego na ReadOnlySpan<char> w sposób wydajny, poza ręczną implementacją przełącznika i optymalizacją.
Aby zachęcić do przyjęcia ReadOnlySpan<char> zezwalamy na dopasowywanie wzorca ReadOnlySpan<char>na stałym string, co pozwala również na jego użycie w przełączniku.
static bool Is123(ReadOnlySpan<char> s)
{
return s is "123";
}
static bool IsABC(Span<char> s)
{
return s switch { "ABC" => true, _ => false };
}
Szczegółowy projekt
Zmieniamy spec dla stałych wzorców w sposób następujący (proponowany dodatek jest wyświetlany pogrubioną czcionką):
Biorąc pod uwagę wartość wejściową wzorca
ei stały wzorzecPz przekonwertowaną wartościąv,
- jeśli e ma typ całkowity lub typ wyliczeniowy albo formę dopuszczaną do wartości null jednego z nich, a v ma typ całkowity, wzorzec
Ppasuje wartości e, jeśli wynik wyrażeniae == vjesttrue; inaczej- Jeśli e jest typu
System.Span<char>lubSystem.ReadOnlySpan<char>, a c jest ciągiem stałym, a c nie ma stałej wartościnull, wzorzec jest traktowany jako zgodny, jeśliSystem.MemoryExtensions.SequenceEqual<char>(e, System.MemoryExtensions.AsSpan(c))zwracatrue.- wzorzec
Ppasuje wartości e, jeśliobject.Equals(e, v)zwraca wartośćtrue.
Dobrze znani członkowie
System.Span<T> i System.ReadOnlySpan<T> są dopasowywane według nazwy, muszą być ref structs i można je zdefiniować poza corlibem.
System.MemoryExtensions pasuje do nazwy i można go zdefiniować poza corlib.
Podpis przeciążeń System.MemoryExtensions.SequenceEqual musi być zgodny z następującymi elementami:
public static bool SequenceEqual<T>(System.Span<T>, System.ReadOnlySpan<T>)public static bool SequenceEqual<T>(System.ReadOnlySpan<T>, System.ReadOnlySpan<T>)
Podpis System.MemoryExtensions.AsSpan musi być zgodny z następującymi elementami:
public static System.ReadOnlySpan<char> AsSpan(string)
Metody z opcjonalnymi parametrami są wykluczone z uwagi.
Minusy
Żaden
Alternatywy
Żaden
Nierozwiązane pytania
Czy dopasowanie powinno być definiowane niezależnie od
MemoryExtensions.SequenceEqual()itp.?... wzorzec jest uznawany za zgodny, jeśli
e.Length == c.Lengthie[i] == c[i]są takie same dla wszystkich znaków we.Zalecenie: zdefiniuj
MemoryExtensions.SequenceEqual()dla wydajności. Jeśli brakujeMemoryExtensions, zgłoś błąd kompilacji.Czy dopuszczalne jest dopasowanie do
(string)null?Jeśli tak, czy
(string)nullpodsumować""odMemoryExtensions.AsSpan(null) == MemoryExtensions.AsSpan("")?static bool IsEmpty(ReadOnlySpan<char> span) { return span switch { (string)null => true, // ok? "" => true, // error: unreachable? _ => false, }; }Zalecenie: wzorzec stały
(string)nullpowinien być zgłaszany jako błąd.Czy wzorzec stały powinien zawierać test typu środowiska uruchomieniowego wartości wyrażenia dla
Span<char>lubReadOnlySpan<char>?static bool Is123<T>(Span<T> s) { return s is "123"; // test for Span<char>? } static bool IsABC<T>(Span<T> s) { return s is Span<char> and "ABC"; // ok? } static bool IsEmptyString<T>(T t) where T : ref struct { return t is ""; // test for ReadOnlySpan<char>, Span<char>, string? }Zalecenie: brak niejawnego testu typu środowiska uruchomieniowego dla wzorca stałego. (
IsABC<T>()przykład jest dozwolony, ponieważ test typu jest jawny.To zalecenie nie zostało zaimplementowane. Wszystkie powyższe przykłady generują błąd kompilatora.
Czy subsumcja powinna uwzględniać stałe wzorce ciągów, wzorce list i wzorzec właściwości
Length?static int ToNum(ReadOnlySpan<char> s) { return s switch { { Length: 0 } => 0, "" => 1, // error: unreachable? ['A',..] => 2, "ABC" => 3, // error: unreachable? _ => 4, }; }Zalecenie: To samo zachowanie subsumcji, które jest stosowane, gdy wartość wyrażenia wynosi
string. (Czy to oznacza brak podsumpcji między ciągami stałymi, wzorcami listy iLength, oprócz traktowania[..]jako dopasowujący się do wszystkich?)
Spotkania projektowe
C# feature specifications