Rune Struktura

Definice

Představuje skalární hodnotu unicode ([ U+0000..U+D7FF ], včetně; nebo [ U+E000.. U+10FFFF ], včetně).

public value class Rune : IComparable, IComparable<System::Text::Rune>, IEquatable<System::Text::Rune>
public value class Rune : IComparable, IComparable<System::Text::Rune>, IEquatable<System::Text::Rune>, ISpanFormattable
public value class Rune : IComparable, IComparable<System::Text::Rune>, IEquatable<System::Text::Rune>, ISpanFormattable, IUtf8SpanFormattable
public value class Rune : IComparable<System::Text::Rune>, IEquatable<System::Text::Rune>
public readonly struct Rune : IComparable, IComparable<System.Text.Rune>, IEquatable<System.Text.Rune>
public readonly struct Rune : IComparable, IComparable<System.Text.Rune>, IEquatable<System.Text.Rune>, ISpanFormattable
public readonly struct Rune : IComparable, IComparable<System.Text.Rune>, IEquatable<System.Text.Rune>, ISpanFormattable, IUtf8SpanFormattable
public readonly struct Rune : IComparable<System.Text.Rune>, IEquatable<System.Text.Rune>
type Rune = struct
type Rune = struct
    interface ISpanFormattable
    interface IFormattable
type Rune = struct
    interface IFormattable
    interface ISpanFormattable
type Rune = struct
    interface IFormattable
    interface ISpanFormattable
    interface IUtf8SpanFormattable
Public Structure Rune
Implements IComparable, IComparable(Of Rune), IEquatable(Of Rune)
Public Structure Rune
Implements IComparable, IComparable(Of Rune), IEquatable(Of Rune), ISpanFormattable
Public Structure Rune
Implements IComparable, IComparable(Of Rune), IEquatable(Of Rune), ISpanFormattable, IUtf8SpanFormattable
Public Structure Rune
Implements IComparable(Of Rune), IEquatable(Of Rune)
Dědičnost
Implementuje

Poznámky

Instance Rune představuje skalární hodnotu Unicode, což znamená jakýkoli bod kódu, který nezahrnuje náhradní rozsah (U+D800. U+DFFF). Konstruktory typu a operátory převodu ověřují vstup, takže příjemci můžou volat rozhraní API za předpokladu, že je základní Rune instance ve správném formátu.

Pokud neznáte termíny skalární hodnota Unicode, bod kódu, náhradní rozsah a dobře tvarované, přečtěte si téma Úvod do kódování znaků v .NET.

Následující části vysvětlují:

Kdy použít typ Rune

Použití typu zvažte, Rune pokud váš kód:

  • Volání rozhraní API, která vyžadují skalární hodnoty unicode
  • Explicitně zpracovává náhradní páry.

Rozhraní API, která vyžadují skalární hodnoty unicode

Pokud váš kód iteruje char instancemi v objektu ReadOnlySpan<char>string nebo , nebudou char některé metody správně fungovat u char instancí, které jsou v náhradním rozsahu. Například následující rozhraní API vyžadují, aby skalární hodnota char fungovala správně:

Následující příklad ukazuje kód, který nebude správně fungovat, pokud jsou některé instance char náhradními body kódu:

// THE FOLLOWING METHOD SHOWS INCORRECT CODE.
// DO NOT DO THIS IN A PRODUCTION APPLICATION.
int CountLettersBadExample(string s)
{
    int letterCount = 0;

    foreach (char ch in s)
    {
        if (char.IsLetter(ch))
        { letterCount++; }
    }

    return letterCount;
}
// THE FOLLOWING METHOD SHOWS INCORRECT CODE.
// DO NOT DO THIS IN A PRODUCTION APPLICATION.
let countLettersBadExample (s: string) =
    let mutable letterCount = 0

    for ch in s do
        if Char.IsLetter ch then
            letterCount <- letterCount + 1
    
    letterCount

Tady je ekvivalentní kód, který funguje s ReadOnlySpan<char>:

// THE FOLLOWING METHOD SHOWS INCORRECT CODE.
// DO NOT DO THIS IN A PRODUCTION APPLICATION.
static int CountLettersBadExample(ReadOnlySpan<char> span)
{
    int letterCount = 0;

    foreach (char ch in span)
    {
        if (char.IsLetter(ch))
        { letterCount++; }
    }

    return letterCount;
}

Předchozí kód funguje správně v některých jazycích, jako je angličtina:

CountLettersInString("Hello")
// Returns 5

Nebude ale správně fungovat pro jazyky mimo základní vícejazyčnou rovinu, jako je například Osage:

CountLettersInString("𐓏𐓘𐓻𐓘𐓻𐓟 𐒻𐓟")
// Returns 0

Důvodem, proč tato metoda vrací nesprávné výsledky pro text Osage, je, že char instance pro písmena Osage jsou náhradní kódové body. Žádný náhradní kódový bod nemá dostatek informací k určení, jestli se jedná o dopis.

Pokud změníte tento kód tak, aby používal Rune místo char, metoda funguje správně s body kódu mimo základní vícejazyčnou rovinu:

int CountLetters(string s)
{
    int letterCount = 0;

    foreach (Rune rune in s.EnumerateRunes())
    {
        if (Rune.IsLetter(rune))
        { letterCount++; }
    }

    return letterCount;
}
let countLetters (s: string) =
    let mutable letterCount = 0

    for rune in s.EnumerateRunes() do
        if Rune.IsLetter rune then
            letterCount <- letterCount + 1

    letterCount

Tady je ekvivalentní kód, který funguje s ReadOnlySpan<char>:

static int CountLetters(ReadOnlySpan<char> span)
{
    int letterCount = 0;

    foreach (Rune rune in span.EnumerateRunes())
    {
        if (Rune.IsLetter(rune))
        { letterCount++; }
    }

    return letterCount;
}

Předchozí kód správně počítá písmena Osage:

CountLettersInString("𐓏𐓘𐓻𐓘𐓻𐓟 𐒻𐓟")
// Returns 8

Kód, který explicitně zpracovává náhradní páry

Použití typu zvažte, Rune pokud váš kód volá rozhraní API, která explicitně pracují s náhradními body kódu, například následující metody:

Například následující metoda má speciální logiku pro práci se náhradními char páry:

static void ProcessStringUseChar(string s)
{
    Console.WriteLine("Using char");

    for (int i = 0; i < s.Length; i++)
    {
        if (!char.IsSurrogate(s[i]))
        {
            Console.WriteLine($"Code point: {(int)(s[i])}");
        }
        else if (i + 1 < s.Length && char.IsSurrogatePair(s[i], s[i + 1]))
        {
            int codePoint = char.ConvertToUtf32(s[i], s[i + 1]);
            Console.WriteLine($"Code point: {codePoint}");
            i++; // so that when the loop iterates it's actually +2
        }
        else
        {
            throw new Exception("String was not well-formed UTF-16.");
        }
    }
}

Takový kód je jednodušší, pokud používá Rune, jako v následujícím příkladu:

static void ProcessStringUseRune(string s)
{
    Console.WriteLine("Using Rune");

    for (int i = 0; i < s.Length;)
    {
        if (!Rune.TryGetRuneAt(s, i, out Rune rune))
        {
            throw new Exception("String was not well-formed UTF-16.");
        }

        Console.WriteLine($"Code point: {rune.Value}");
        i += rune.Utf16SequenceLength; // increment the iterator by the number of chars in this Rune
    }
}

Kdy nepoužívat atribut Rune

Typ nemusíte používat, Rune pokud váš kód:

  • Hledá přesné char shody.
  • Rozdělí řetězec na hodnotu známého znaku.

Rune Použití typu může vrátit nesprávné výsledky, pokud kód:

  • Spočítá počet zobrazovaných znaků v string

Vyhledání přesných shod char

Následující kód iteruje hledáním string konkrétních znaků a vrátí index první shody. Tento kód není nutné měnit tak, aby používal Rune, protože kód hledá znaky, které jsou reprezentované jedním char.

int GetIndexOfFirstAToZ(string s)
{
    for (int i = 0; i < s.Length; i++)
    {
        char thisChar = s[i];
        if ('A' <= thisChar && thisChar <= 'Z')
        {
            return i; // found a match
        }
    }

    return -1; // didn't find 'A' - 'Z' in the input string
}

Rozdělení řetězce na známý char

Je běžné volat string.Split a používat oddělovače, jako ' ' je (mezera) nebo ',' (čárka), jako v následujícím příkladu:

string inputString = "🐂, 🐄, 🐆";
string[] splitOnSpace = inputString.Split(' ');
string[] splitOnComma = inputString.Split(',');

Zde není nutné používat Rune , protože kód hledá znaky, které jsou reprezentovány jedním char.

Určení počtu zobrazovaných znaků v string

Počet Rune instancí v řetězci nemusí odpovídat počtu uživatelsky vnímatelných znaků zobrazených při zobrazení řetězce.

Vzhledem k tomu Rune , že instance představují skalární hodnoty Unicode, komponenty, které dodržují pravidla segmentace textu Unicode , mohou použít Rune jako stavební blok pro počítání zobrazovaných znaků.

Tento StringInfo typ se dá použít k počítání zobrazovaných znaků, ale nepočítá se správně ve všech scénářích pro jiné implementace .NET než .NET 5+.

Další informace najdete v tématu Clustery Grapheme.

Jak vytvořit instanci Rune

Existuje několik způsobů, jak získat Rune instanci. Konstruktor můžete použít k vytvoření objektu Rune přímo z:

  • Bod kódu.

    Rune a = new Rune(0x0061); // LATIN SMALL LETTER A
    Rune b = new Rune(0x10421); // DESERET CAPITAL LETTER ER
    
  • Jeden .char

    Rune c = new Rune('a');
    
  • Náhradní char pár.

    Rune d = new Rune('\ud83d', '\udd2e'); // U+1F52E CRYSTAL BALL
    

Všechny konstruktory vyvolají znak , ArgumentException pokud vstup nepředstavuje platnou skalární hodnotu Unicode.

Rune.TryCreate Existují metody dostupné pro volající, kteří nechtějí, aby při selhání došlo k výjimkám.

Rune instance lze také číst z existujících vstupních sekvencí. Pokud například ReadOnlySpan<char> metoda představuje data UTF-16, Rune.DecodeFromUtf16 vrátí první Rune instanci na začátku vstupního rozsahu. Metoda Rune.DecodeFromUtf8 funguje podobně a přijímá ReadOnlySpan<byte> parametr, který představuje data UTF-8. Existují ekvivalentní metody čtení od konce rozsahu místo od začátku spanu.

Vlastnosti dotazu objektu Rune

Chcete-li získat celočíselnou hodnotu Rune bodu kódu instance, použijte Rune.Value vlastnost .

Rune rune = new Rune('\ud83d', '\udd2e'); // U+1F52E CRYSTAL BALL
int codePoint = rune.Value; // = 128302 decimal (= 0x1F52E)

Řada statických rozhraní API dostupných pro tento char typ je také k dispozici pro typ Rune . Například Rune.IsWhiteSpace a Rune.GetUnicodeCategory jsou ekvivalenty Char.IsWhiteSpace metod a Char.GetUnicodeCategory . Metody Rune správně zpracovávají náhradní páry.

Následující příklad kódu vezme ReadOnlySpan<char> jako vstup a ořízne od začátku i konce rozpětí každý Rune , co není písmeno nebo číslice.

static ReadOnlySpan<char> TrimNonLettersAndNonDigits(ReadOnlySpan<char> span)
{
    // First, trim from the front.
    // If any Rune can't be decoded
    // (return value is anything other than "Done"),
    // or if the Rune is a letter or digit,
    // stop trimming from the front and
    // instead work from the end.
    while (Rune.DecodeFromUtf16(span, out Rune rune, out int charsConsumed) == OperationStatus.Done)
    {
        if (Rune.IsLetterOrDigit(rune))
        { break; }
        span = span[charsConsumed..];
    }

    // Next, trim from the end.
    // If any Rune can't be decoded,
    // or if the Rune is a letter or digit,
    // break from the loop, and we're finished.
    while (Rune.DecodeLastFromUtf16(span, out Rune rune, out int charsConsumed) == OperationStatus.Done)
    {
        if (Rune.IsLetterOrDigit(rune))
        { break; }
        span = span[..^charsConsumed];
    }

    return span;
}

Mezi a RunerozhraníMI API existují určité rozdílychar. Příklad:

Převod na Rune UTF-8 nebo UTF-16

Vzhledem k tomu, že Rune je skalární hodnota Unicode, lze ji převést na kódování UTF-8, UTF-16 nebo UTF-32. Typ Rune má integrovanou podporu převodu na UTF-8 a UTF-16.

Rune Převede Rune.EncodeToUtf16 instanci na char instance. Pokud chcete zadat dotaz na počet char instancí, které by byly výsledkem převodu Rune instance na UTF-16, použijte Rune.Utf16SequenceLength vlastnost . Podobné metody existují i pro převod UTF-8.

Následující příklad převede Rune instanci na char pole. Kód předpokládá, že máte Rune instanci v rune proměnné :

char[] chars = new char[rune.Utf16SequenceLength];
int numCharsWritten = rune.EncodeToUtf16(chars);

Vzhledem k tomu, že je string posloupnost znaků UTF-16, převede Rune následující příklad také instanci na UTF-16:

string theString = rune.ToString();

Následující příklad převede Rune instanci na bajtové UTF-8 pole:

byte[] bytes = new byte[rune.Utf8SequenceLength];
int numBytesWritten = rune.EncodeToUtf8(bytes);

Metody Rune.EncodeToUtf16 a Rune.EncodeToUtf8 vrátí skutečný počet zapsaných prvků. Pokud je cílová vyrovnávací paměť příliš krátká na to, aby obsahovala výsledek, vyvolá výjimku. Pro volající, kteří se chtějí vyhnout výjimkám, existují i metody, TryEncodeToUtf16 které nevyvolávajíTryEncodeToUtf8.

Spuštění v .NET a v jiných jazycích

Termín "rune" není definován ve standardu Unicode. Termín se datuje do vytvoření UTF-8. Rob Pike a Ken Thompson hledali termín, který by popsal to, co se nakonec stalo známým jako bod kódu. Usadili se na termínu "rune" a pozdější vliv Roba Pikeho na programovací jazyk Go pomohl tento termín popularizovat.

Typ .NET Rune však není ekvivalentem typu Go rune . V Go rune je typ aliasem pro int32. Rune Go je určena k reprezentaci bodu kódu Unicode, ale může to být libovolná 32bitová hodnota, včetně náhradních bodů kódu a hodnot, které nejsou zákonnými body kódu Unicode.

Podobné typy v jiných programovacích jazycích najdete v článku Rustův primitivní char typ nebo typ SwiftuUnicode.Scalar, které představují skalární hodnoty Unicode. Poskytují podobné funkce jako . Rune NET a nepovolují vytváření instancí hodnot, které nejsou zákonnými skalárními hodnotami Unicode.

Konstruktory

Rune(Char)

Vytvoří z Rune poskytnuté jednotky kódu UTF-16.

Rune(Char, Char)

Vytvoří z Rune poskytnutého náhradního páru UTF-16.

Rune(Int32)

Vytvoří Rune ze zadaného 32bitového celého čísla, které představuje skalární hodnotu Unicode.

Rune(UInt32)

Vytvoří Rune ze zadaného 32bitového celého čísla bez znaménka, které představuje skalární hodnotu Unicode.

Vlastnosti

IsAscii

Získá hodnotu, která označuje, zda skalární hodnota přidružená k tomu Rune je v rozsahu kódování ASCII.

IsBmp

Získá hodnotu, která označuje, zda skalární hodnota přidružená k tomu Rune je v rozsahu kódování BMP.

Plane

Získá rovinu Unicode (0 až 16 včetně), která obsahuje tento skalární.

ReplacementChar

Rune Získá instanci, která představuje znak nahrazení Unicode U+FFFD.

Utf16SequenceLength

Získá délku v jednotkách kódu (Char) sekvence UTF-16 vyžadované k reprezentaci této skalární hodnoty.

Utf8SequenceLength

Získá délku v jednotkách kódu sekvence UTF-8 požadované k reprezentaci této skalární hodnoty.

Value

Získá skalární hodnotu Unicode jako celé číslo.

Metody

CompareTo(Rune)

Porovná aktuální instanci se zadanou Rune instancí.

DecodeFromUtf16(ReadOnlySpan<Char>, Rune, Int32)

Dekóduje Rune na začátku poskytnuté zdrojové vyrovnávací paměti UTF-16.

DecodeFromUtf8(ReadOnlySpan<Byte>, Rune, Int32)

Dekóduje Rune na začátku poskytnuté zdrojové vyrovnávací paměti UTF-8.

DecodeLastFromUtf16(ReadOnlySpan<Char>, Rune, Int32)

Dekóduje Rune na konci poskytnuté zdrojové vyrovnávací paměti UTF-16.

DecodeLastFromUtf8(ReadOnlySpan<Byte>, Rune, Int32)

Dekóduje na Rune konci poskytnuté zdrojové vyrovnávací paměti UTF-8.

EncodeToUtf16(Span<Char>)

Zakóduje ji Rune do cílové vyrovnávací paměti UTF-16.

EncodeToUtf8(Span<Byte>)

Zakóduje ji Rune do cílové vyrovnávací paměti UTF-8.

Equals(Object)

Vrátí hodnotu, která označuje, zda aktuální instance a zadaný objekt jsou si rovny.

Equals(Rune)

Vrátí hodnotu, která označuje, zda jsou aktuální instance a zadaná rune rovny.

GetHashCode()

Vrátí hodnotu hash pro tuto instanci.

GetNumericValue(Rune)

Získá číselnou hodnotu přidruženou k zadané rune.

GetRuneAt(String, Int32)

Získá, Rune který začíná na zadané pozici v řetězci.

GetUnicodeCategory(Rune)

Získá unicode kategorie přidružené k zadané rune.

IsControl(Rune)

Vrátí hodnotu, která označuje, zda je zadaná rune zařazena do kategorie jako znak ovládacího prvku.

IsDigit(Rune)

Vrátí hodnotu, která označuje, zda je zadaná rune zařazena do kategorií jako desetinná číslice.

IsLetter(Rune)

Vrátí hodnotu, která označuje, zda je zadaná rune zařazena do kategorií jako písmeno.

IsLetterOrDigit(Rune)

Vrátí hodnotu, která označuje, zda je zadaná rune zařazena do kategorií jako písmeno nebo desetinná číslice.

IsLower(Rune)

Vrátí hodnotu, která označuje, zda je zadaná rune zařazena do kategorií jako malé písmeno.

IsNumber(Rune)

Vrátí hodnotu, která označuje, zda je zadaná runa zařazena do kategorie jako číslo.

IsPunctuation(Rune)

Vrátí hodnotu, která označuje, zda je zadaná rune zařazena do kategorie jako interpunkční znaménko.

IsSeparator(Rune)

Vrátí hodnotu, která označuje, zda je zadaná rune zařazena do kategorií jako znak oddělovače.

IsSymbol(Rune)

Vrátí hodnotu, která označuje, zda je zadaná rune zařazena do kategorií jako znak symbolu.

IsUpper(Rune)

Vrátí hodnotu, která označuje, zda je zadaná rune zařazena do kategorií jako velké písmeno.

IsValid(Int32)

Vrátí hodnotu, která označuje, zda 32bitové znaménkové celé číslo představuje platnou skalární hodnotu Unicode; to znamená, že je v rozsahu [U+0000..U+D7FF ], včetně; nebo [ U+E000.. U+10FFFF ] včetně.

IsValid(UInt32)

Vrátí hodnotu, která označuje, zda 32bitové celé číslo bez znaménka představuje platnou skalární hodnotu Unicode; to znamená, že je v rozsahu [ U+0000..U+D7FF ], včetně nebo [ U+E000.. U+10FFFF ] včetně.

IsWhiteSpace(Rune)

Vrátí hodnotu, která označuje, zda je zadaná rune zařazena do kategorií jako prázdný znak.

ToLower(Rune, CultureInfo)

Vrátí kopii zadaného Rune převedeného na malá písmena pomocí pravidel pro velká písmena zadané jazykové verze.

ToLowerInvariant(Rune)

Vrátí kopii zadaného Rune převedeného na malá písmena pomocí pravidel pro velká písmena invariantní jazykové verze.

ToString()

Vrátí řetězcovou reprezentaci této Rune instance.

ToUpper(Rune, CultureInfo)

Vrátí kopii zadaného Rune převedeného na velká písmena pomocí pravidel pro velká písmena zadané jazykové verze.

ToUpperInvariant(Rune)

Vrátí kopii zadaného Rune převedeného na velká písmena pomocí pravidel pro velká písmena invariantní jazykové verze.

TryCreate(Char, Char, Rune)

Pokusí se Rune vytvořit ze zadaného náhradního páru UTF-16 a vrátí hodnotu, která označuje, zda byla operace úspěšná.

TryCreate(Char, Rune)

Pokusí se vytvořit Rune ze zadaného znaku a vrátí hodnotu, která označuje, zda byla operace úspěšná.

TryCreate(Int32, Rune)

Pokusí se Rune vytvořit ze zadaného celého čísla se znaky, které představuje skalární hodnotu Unicode.

TryCreate(UInt32, Rune)

Pokusí se Rune vytvořit ze zadaného 32bitového celého čísla bez znaménka, které představuje skalární hodnotu Unicode.

TryEncodeToUtf16(Span<Char>, Int32)

Zakóduje ji Rune do cílové vyrovnávací paměti s kódováním UTF-16.

TryEncodeToUtf8(Span<Byte>, Int32)

Zakóduje ji Rune do cílové vyrovnávací paměti s kódováním UTF-8.

TryGetRuneAt(String, Int32, Rune)

Pokusí se získat Rune hodnotu, která začíná na zadané pozici v řetězci, a vrátí hodnotu, která označuje, zda operace byla úspěšná.

Operátory

Equality(Rune, Rune)

Vrátí hodnotu, která označuje, zda jsou dvě Rune instance rovny.

Explicit(Char to Rune)

Definuje explicitní převod 16bitového znaku Unicode na Rune.

Explicit(Int32 to Rune)

Definuje explicitní převod celého čísla se 32bitovým signedm Runena .

Explicit(UInt32 to Rune)

Definuje explicitní převod 32bitového celého čísla bez znaménka Runena .

GreaterThan(Rune, Rune)

Vrátí hodnotu označující, zda je zadaná Rune hodnota větší než jiná zadaná Runehodnota .

GreaterThanOrEqual(Rune, Rune)

Vrátí hodnotu označující, zda je zadaná Rune hodnota větší nebo rovna jinému zadanému objektu Rune.

Inequality(Rune, Rune)

Vrátí hodnotu, která označuje, zda mají dvě Rune instance různé hodnoty.

LessThan(Rune, Rune)

Vrátí hodnotu označující, zda je zadaná Rune hodnota menší než jiná zadaná Runehodnota .

LessThanOrEqual(Rune, Rune)

Vrátí hodnotu označující, zda je zadaná Rune hodnota menší nebo rovna jiné zadané hodnotě Rune.

Explicitní implementace rozhraní

IComparable.CompareTo(Object)

Porovná aktuální instanci se zadaným objektem.

IFormattable.ToString(String, IFormatProvider)

Formátuje hodnotu aktuální instance pomocí zadaného formátu.

ISpanFormattable.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)

Pokusí se naformátovat hodnotu aktuální instance do zadaného rozsahu znaků.

IUtf8SpanFormattable.TryFormat(Span<Byte>, Int32, ReadOnlySpan<Char>, IFormatProvider)

Představuje skalární hodnotu unicode ([ U+0000..U+D7FF ], včetně; nebo [ U+E000.. U+10FFFF ], včetně).

Platí pro