Megosztás a következőn keresztül:


Mintaegyezés Span<char> állandó sztringen

Jegyzet

Ez a cikk egy funkcióspecifikáció. A specifikáció a funkció tervezési dokumentumaként szolgál. Tartalmazza a specifikáció javasolt módosításait, valamint a funkció tervezése és fejlesztése során szükséges információkat. Ezeket a cikkeket mindaddig közzéteszik, amíg a javasolt specifikációmódosításokat nem véglegesítik, és be nem építik a jelenlegi ECMA-specifikációba.

A szolgáltatás specifikációja és a befejezett implementáció között eltérések lehetnek. Ezeket a különbségeket a vonatkozó nyelvi tervezési értekezlet (LDM) megjegyzései rögzítik.

A funkcióspektusok C# nyelvi szabványba való bevezetésének folyamatáról a specifikációkcímű cikkben olvashat bővebben.

Bajnoki probléma: https://github.com/dotnet/csharplang/issues/8640

Összefoglalás

Engedélyezze a Span<char> és a ReadOnlySpan<char> mintázat illesztését egy állandó sztringben.

Motiváció

A teljesítmény szempontjából sok esetben előnyben részesítik a Span<char> és a ReadOnlySpan<char> használatát a szöveggel szemben. A keretrendszer számos új API-t adott hozzá, amelyek lehetővé teszik a ReadOnlySpan<char> használatát egy stringhelyett.

A sztringeken végzett gyakori művelet egy vezérlő utasítás használata annak ellenőrzésére, hogy az adott értékkel egyezik-e, és a fordító optimalizálja az ilyen vezérlő utasítást. Azonban jelenleg nem lehet hatékonyan elvégezni ugyanezt egy ReadOnlySpan<char>-n, kivéve ha a kapcsolót és az optimalizálást manuálisan hajtják végre.

A ReadOnlySpan<char> bevezetésének ösztönzése érdekében lehetővé tesszük a mintázat illesztését egy ReadOnlySpan<char>egyezés során egy állandó stringellen, így lehetővé teszi annak használatát egy switch-ben is.

static bool Is123(ReadOnlySpan<char> s)
{
    return s is "123";
}

static bool IsABC(Span<char> s)
{
    return s switch { "ABC" => true, _ => false };
}

Részletes kialakítás

Az állandó minták specifikációját az alábbiak szerint módosítjuk: (a javasolt kiegészítés félkövérben jelenik meg)

Az adott minta bemeneti értéke e és egy állandó minta P konvertált értékével v,

  • ha e integráltípussal vagy számtípussal rendelkezik, vagy ezek egyikének null értékű formája van, és v integráltípussal rendelkezik, a minta Pmegegyezike, ha a kifejezés eredménye e == vtrue; egyébként
  • Ha eSystem.Span<char> vagy System.ReadOnlySpan<char>típusú, és c állandó sztring, és c nem rendelkezik állandó nullértékkel, akkor a minta akkor tekinthető egyezőnek, ha System.MemoryExtensions.SequenceEqual<char>(e, System.MemoryExtensions.AsSpan(c))truead vissza .
  • a minta Pmegegyezik a értékkel, ha object.Equals(e, v) visszaadja a trueértéket.

Jól ismert tagok

System.Span<T> és System.ReadOnlySpan<T> név szerint egyeznek, ref structs-nek kell lenniük, és a corlibon kívül is definiálhatók.

System.MemoryExtensions név alapján van megadva, és a Corlibon kívül is definiálható.

A System.MemoryExtensions.SequenceEqual túlterhelések aláírásának meg kell egyeznie:

  • public static bool SequenceEqual<T>(System.Span<T>, System.ReadOnlySpan<T>)
  • public static bool SequenceEqual<T>(System.ReadOnlySpan<T>, System.ReadOnlySpan<T>)

A System.MemoryExtensions.AsSpan aláírásának meg kell egyeznie:

  • public static System.ReadOnlySpan<char> AsSpan(string)

Az opcionális paraméterekkel rendelkező metódusok nem kerülnek figyelembe vételre.

Hátránya

Egyik sem

Alternatívák

Egyik sem

Megoldatlan kérdések

  1. Az egyeztetést a MemoryExtensions.SequenceEqual() stb.-től függetlenül kell meghatározni?

    ... a minta akkor tekinthető egyezőnek, ha e.Length == c.Length és e[i] == c[i] minden karakterére igaz az e-ben.

    Javaslat: Határozza meg MemoryExtensions.SequenceEqual() segítségével a teljesítményt. Ha MemoryExtensions hiányzik, jelentse a fordítási hibát.

  2. Megengedjük a (string)null egyeztetését?

    Ha igen, (string)null magába foglalja ""-et a MemoryExtensions.AsSpan(null) == MemoryExtensions.AsSpan("")következtében?

    static bool IsEmpty(ReadOnlySpan<char> span)
    {
        return span switch
        {
            (string)null => true, // ok?
            "" => true,           // error: unreachable?
            _ => false,
        };
    }
    

    javaslat: Az állandó minta (string)null hibaként kell jelenteni.

  3. Az állandó mintaegyezésnek tartalmaznia kell-e a Span<char> vagy ReadOnlySpan<char>kifejezésértékének futásidejű tesztelését?

    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?
    }
    

    Javaslat: Nincs implicit futásidejű típusteszt az állandó mintához. (IsABC<T>() példa azért engedélyezett, mert a típusteszt explicit.)

    Ez a javaslat nem lett megvalósítva. Az összes fenti minta fordítóhibát okoz.

  4. Számításba kell venni a konstans sztringmintákat, a listamintákat és a Length tulajdonságmintát a részhalmaz-meghatározás során?

    static int ToNum(ReadOnlySpan<char> s)
    {
        return s switch
        {
            { Length: 0 } => 0,
            "" => 1,        // error: unreachable?
            ['A',..] => 2,
            "ABC" => 3,     // error: unreachable?
            _ => 4,
        };
    }
    

    Javaslat: Ugyanazt az alárendelési viselkedést alkalmazzuk, mint amikor a kifejezés értéke string. Ez azt jelenti, hogy az állandó sztringek, a listaminták és a Lengthközött nincs alárendeltség, kivéve, ha a [..]-et úgy kezeli, mint ami bármihez illeszkedik?

Tervező értekezletek

https://github.com/dotnet/csharplang/blob/master/meetings/2020/LDM-2020-10-07.md#readonlyspanchar-patterns