Patroonovereenkomst Span<char>
op een constante tekenreeks
Notitie
Dit artikel is een functiespecificatie. De specificatie fungeert als het ontwerpdocument voor de functie. Het bevat voorgestelde specificatiewijzigingen, samen met informatie die nodig is tijdens het ontwerp en de ontwikkeling van de functie. Deze artikelen worden gepubliceerd totdat de voorgestelde specificaties zijn voltooid en opgenomen in de huidige ECMA-specificatie.
Er kunnen enkele verschillen zijn tussen de functiespecificatie en de voltooide implementatie. Deze verschillen worden vastgelegd in de relevante LDM (Language Design Meeting) notities.
Meer informatie over het proces voor het aannemen van functiespeclets in de C#-taalstandaard vindt u in het artikel over de specificaties.
Kampioenprobleem: https://github.com/dotnet/csharplang/issues/8640
Samenvatting
Sta patroonmatching toe van een Span<char>
en een ReadOnlySpan<char>
op een constante string.
Motivatie
Voor performance heeft het gebruik van Span<char>
en ReadOnlySpan<char>
de voorkeur boven strings in veel scenario's. Het framework heeft veel nieuwe API's toegevoegd waarmee u ReadOnlySpan<char>
kunt gebruiken in plaats van een string
.
Een veelvoorkomende bewerking voor tekenreeksen is het gebruik van een switch-instructie om te testen of het een bepaalde waarde is, waarbij de compiler zo'n switch optimaliseert. Er is momenteel echter geen manier om hetzelfde te doen op een ReadOnlySpan<char>
efficiënt, behalve het handmatig implementeren van de switch en de optimalisatie.
Om de acceptatie van ReadOnlySpan<char>
te bevorderen, staan we toe dat een patroon dat overeenkomt met een ReadOnlySpan<char>
, op een constante string
wordt gebruikt, zodat het ook in een switch kan worden toegepast.
static bool Is123(ReadOnlySpan<char> s)
{
return s is "123";
}
static bool IsABC(Span<char> s)
{
return s switch { "ABC" => true, _ => false };
}
Gedetailleerd ontwerp
We wijzigen de specificatie voor constante patronen als volgt (de voorgestelde toevoeging wordt vet weergegeven):
Gezien een patrooninvoerwaarde
e
en een constant patroonP
met geconverteerde waardev
,
- als e integraal type of opsommingstype heeft, of een null-vorm van een van deze, en v integraal type heeft, komt het patroon
P
overeen met de waarde e als het resultaat van de expressiee == v
true
is; anders- Als e van het type
System.Span<char>
ofSystem.ReadOnlySpan<char>
is en c een constante tekenreeks is en c- geen constante waarde vannull
heeft, wordt het patroon beschouwd als overeenkomend alsSystem.MemoryExtensions.SequenceEqual<char>(e, System.MemoryExtensions.AsSpan(c))
true
retourneert.- Het patroon
P
komt overeen met de waarde e wanneerobject.Equals(e, v)
true
retourneert.
Bekende leden
System.Span<T>
en System.ReadOnlySpan<T>
overeenkomen met de naam, moeten ref struct
zijn en kunnen buiten corlib worden gedefinieerd.
System.MemoryExtensions
wordt op naam vergeleken en kan buiten corlib worden gedefinieerd.
De signatuur van System.MemoryExtensions.SequenceEqual
overloads moet overeenkomen:
public static bool SequenceEqual<T>(System.Span<T>, System.ReadOnlySpan<T>)
public static bool SequenceEqual<T>(System.ReadOnlySpan<T>, System.ReadOnlySpan<T>)
De handtekening van System.MemoryExtensions.AsSpan
moet overeenkomen met:
public static System.ReadOnlySpan<char> AsSpan(string)
Methoden met optionele parameters worden uitgesloten van overweging.
Nadelen
Geen
Alternatieven
Geen
Niet-opgeloste vragen
Moeten overeenkomsten onafhankelijk van
MemoryExtensions.SequenceEqual()
enzovoort worden gedefinieerd?... het patroon wordt beschouwd als overeenkomend als
e.Length == c.Length
ene[i] == c[i]
voor alle tekens ine
.Aanbeveling: definieer in termen van
MemoryExtensions.SequenceEqual()
voor de prestaties. AlsMemoryExtensions
ontbreekt, rapporteert u een compilatiefout.Moet matchen tegen
(string)null
toegestaan worden?Als dat het geval is, moet
(string)null
""
insluiten sindsMemoryExtensions.AsSpan(null) == MemoryExtensions.AsSpan("")
?static bool IsEmpty(ReadOnlySpan<char> span) { return span switch { (string)null => true, // ok? "" => true, // error: unreachable? _ => false, }; }
Aanbeveling: Het constantenpatroon
(string)null
moet als een fout worden gerapporteerd.Moet de constante patroonmatching een runtime-typetest bevatten van de expressiewaarde voor
Span<char>
ofReadOnlySpan<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? }
Aanbeveling: Geen impliciete runtimetypetest voor constant patroon. (
IsABC<T>()
voorbeeld is toegestaan omdat de typetest expliciet is.)Deze aanbeveling is niet geïmplementeerd. Alle voorgaande voorbeelden produceren een compilerfout.
Moet subsumptie rekening houden met constante tekenreekspatronen, lijstpatronen en
Length
-eigenschapspatronen?static int ToNum(ReadOnlySpan<char> s) { return s switch { { Length: 0 } => 0, "" => 1, // error: unreachable? ['A',..] => 2, "ABC" => 3, // error: unreachable? _ => 4, }; }
Aanbeveling: Hetzelfde subsumeringsgedrag dat wordt gebruikt wanneer de expressiewaarde
string
is. (Betekent dit geen subsamenvatting tussen constante tekenreeksen, lijstpatronen enLength
, behalve het behandelen van[..]
als overeenkomende waarden?)
Ontwerpvergaderingen
C# feature specifications