Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Porovnávání vzorů
Poznámka
Tento článek je specifikace funkce. Specifikace slouží jako návrhový dokument pro funkci. Zahrnuje navrhované změny specifikace spolu s informacemi potřebnými při návrhu a vývoji funkce. Tyto články se publikují, dokud nebudou navrhované změny specifikace finalizovány a začleněny do aktuální specifikace ECMA.
Mezi specifikací funkce a dokončenou implementací může docházet k nějakým nesrovnalostem. Tyto rozdíly jsou zachyceny v příslušných poznámkách ze schůzky o návrhu jazyka (LDM) .
Další informace o procesu přijetí specifikací funkcí do jazyka C# najdete v článku o specifikacích .
Problém šampiona: https://github.com/dotnet/csharplang/issues/8640
Shrnutí
Povolte porovnání vzorů Span<char> a ReadOnlySpan<char> na konstantním řetězci.
Motivace
Pro zvýšení výkonu se v mnoha scénářích upřednostňuje používání Span<char> a ReadOnlySpan<char> před řetězcem. Architektura přidala mnoho nových rozhraní API, která umožňují používat ReadOnlySpan<char> místo string.
Běžnou operací s řetězci je použití přepínače k otestování, pokud jde o konkrétní hodnotu, a kompilátor takový přepínač optimalizuje. V současné době ale neexistuje žádný způsob, jak to udělat u ReadOnlySpan<char> efektivně, kromě implementace přepínače a optimalizace ručně.
Abychom podpořili přijetí ReadOnlySpan<char>, umožňujeme přiřazení vzoru ReadOnlySpan<char>ke konstantě string, což rovněž umožňuje jeho použití v přepínači.
static bool Is123(ReadOnlySpan<char> s)
{
return s is "123";
}
static bool IsABC(Span<char> s)
{
return s switch { "ABC" => true, _ => false };
}
Podrobný návrh
Změníme specifikaci pro konstantní vzory následujícím způsobem (navržený dodatek je zobrazen tučně):
Při zadání vstupní hodnoty vzoru
ea konstantního vzoruPs převedenou hodnotouv,
- pokud e má celočíselný typ nebo výčtový typ nebo typ s možnou hodnotou null a v má celočíselný typ,
Pvzor odpovídá hodnotě e, pokud je výsledek výrazue == vtrue; jinak- Pokud je e typu
System.Span<char>neboSystem.ReadOnlySpan<char>a c je konstantní řetězec a c nemá konstantní hodnotunull, pak se vzor považuje za odpovídající, pokudSystem.MemoryExtensions.SequenceEqual<char>(e, System.MemoryExtensions.AsSpan(c))vrátítrue.- vzor
Podpovídá hodnotě e, pokudobject.Equals(e, v)vrátítrue.
Známí členové
System.Span<T> a System.ReadOnlySpan<T> odpovídají názvu, musí být ref structs a dají se definovat mimo corlib.
System.MemoryExtensions se shoduje s názvem a dá se definovat mimo corlib.
Podpis přetížení System.MemoryExtensions.SequenceEqual musí odpovídat:
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 musí odpovídat:
public static System.ReadOnlySpan<char> AsSpan(string)
Metody s volitelnými parametry jsou vyloučeny z úvahy.
Nevýhody
Žádný
Alternativy
Žádný
Nevyřešené otázky
Mělo by být porovnání definováno nezávisle na
MemoryExtensions.SequenceEqual()atd.?Vzor je považován za odpovídající, pokud
e.Length == c.Lengthae[i] == c[i]splňují podmínky pro všechny znaky ve.Doporučení: Definujte výkon z hlediska
MemoryExtensions.SequenceEqual(). PokudMemoryExtensionschybí, nahlaste chybu kompilace.Mělo by být povoleno porovnávání s
(string)null?Pokud ano, mělo by
(string)nullpohltit""odMemoryExtensions.AsSpan(null) == MemoryExtensions.AsSpan("")?static bool IsEmpty(ReadOnlySpan<char> span) { return span switch { (string)null => true, // ok? "" => true, // error: unreachable? _ => false, }; }Doporučení: Konstantní vzor
(string)nullby měl být nahlášen jako chyba.Měla by shoda konstantního vzoru obsahovat běhový test typu hodnoty výrazu pro
Span<char>neboReadOnlySpan<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? }Doporučení: Žádný implicitní test typu modulu runtime pro konstantní vzor. (
IsABC<T>()příklad je povolený, protože test typu je explicitní.)Toto doporučení nebylo implementováno. Všechny předchozí ukázky vytvářejí chybu kompilátoru.
Měli byste při subsumpci zvážit vzory konstantních řetězců, vzory seznamů a vzor vlastností
Length?static int ToNum(ReadOnlySpan<char> s) { return s switch { { Length: 0 } => 0, "" => 1, // error: unreachable? ['A',..] => 2, "ABC" => 3, // error: unreachable? _ => 4, }; }Doporučení: Stejné chování zahrnutí jako při hodnotě výrazu
string. Znamená to, že mezi konstantními řetězci, vzory seznamů aLengthnení žádná subsumpce, kromě případu, kdy je[..]považováno za shodné s jakýmkoli?
Schůzky o designu
C# feature specifications