Rune Estrutura

Definição

Representa um valor escalar Unicode ([ U+0000..U+D7FF ], inclusive; ou [ U+E000.. U+10FFFF ], inclusive).

public value class Rune : IComparable, IComparable<System::Text::Rune>, IEquatable<System::Text::Rune>, ISpanFormattable, IUtf8SpanFormattable, IUtf8SpanParsable<System::Text::Rune>
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>, ISpanFormattable, IUtf8SpanFormattable, IUtf8SpanParsable<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
    interface IFormattable
    interface ISpanFormattable
    interface IUtf8SpanFormattable
    interface IUtf8SpanParsable<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), ISpanFormattable, IUtf8SpanFormattable, IUtf8SpanParsable(Of Rune)
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)
Herança
Implementações

Observações

Uma Rune instância representa um valor escalar Unicode, o que significa qualquer ponto de código excluindo o intervalo substituto (U+D800.. U+DFFF). Os construtores e operadores de conversão do tipo validam a entrada, pelo que os consumidores podem chamar as APIs assumindo que a instância subjacente Rune está bem formada.

Se você não estiver familiarizado com os termos valor escalar Unicode, ponto de código, intervalo substituto e bem formado, consulte Introdução à codificação de caracteres no .NET.

Quando usar o tipo Rune

Considere usar o tipo Rune se o seu código:

  • Chama APIs que exigem valores escalares Unicode
  • Lida explicitamente com pares substitutos

APIs que exigem valores escalares Unicode

Se o seu código iterar através das instâncias char em uma string ou uma ReadOnlySpan<char>, alguns dos métodos char não funcionarão corretamente em instâncias char que estão na faixa substituta. Por exemplo, as APIs a seguir exigem um valor char escalar para funcionar corretamente:

O exemplo a seguir mostra o código que não funcionará corretamente se qualquer uma das char instâncias for pontos de código substitutos:

// 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

Aqui está o código equivalente que funciona com um 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;
}

O código anterior funciona corretamente com alguns idiomas, como o inglês:

CountLettersInString("Hello")
// Returns 5

Mas não funcionará corretamente para idiomas fora do Plano Multilingue Básico, como o Osage:

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

A razão pela qual esse método retorna resultados incorretos para o texto Osage é que as instâncias para letras Osage são char pontos de código suplentes. Nenhum ponto de código substituto tem informações suficientes para determinar se é uma letra.

Se mudar este código para usar Rune em vez de char, o método funciona corretamente com pontos de código fora do Plano Multilíngue Básico.

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

Aqui está o código equivalente que funciona com um ReadOnlySpan<char>:

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

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

    return letterCount;
}

O código anterior conta corretamente as letras de Osage:

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

Código que lida explicitamente com pares substitutos

Considere usar o tipo Rune se o seu código chamar APIs que operam explicitamente em pontos de código substitutos, como os seguintes métodos:

Por exemplo, o seguinte método tem uma lógica especial para lidar com pares substitutos char :

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.");
        }
    }
}

Esse código é mais simples se ele usa Rune, como no exemplo a seguir:

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

Quando não utilizar Rune

Você não precisa usar o tipo Rune se seu código:

  • Procura correspondências exatas char
  • Divide uma cadeia de caracteres em um valor char conhecido

A utilização do Rune tipo poderá resultar em resultados incorretos se o seu código:

  • Conta o número de caracteres de exibição num string

Procure correspondências exatas char

O código a seguir itera através de uma string busca por caracteres específicos, retornando o índice da primeira correspondência. Não há necessidade de alterar esse código para usar Rune, pois o código está procurando caracteres que são representados por um único 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
}

Dividir uma cadeia de caracteres com base em um delimitador conhecido char

É comum chamar string.Split e usar delimitadores como ' ' (espaço) ou ',' (vírgula), como no exemplo a seguir:

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

Não há necessidade de usar Rune aqui, porque o código está procurando caracteres que são representados por um único char.

Contar o número de caracteres de exibição em um string

O número de instâncias numa cadeia de Rune caracteres pode não corresponder ao número de caracteres perceptíveis pelo utilizador quando se exibe a string.

Como Rune as instâncias representam valores escalares Unicode, os componentes que seguem as diretrizes de segmentação de texto Unicode podem usar Rune como um bloco de construção para contar caracteres de exibição.

O StringInfo tipo pode ser usado para contar caracteres de exibição, mas não conta corretamente em todos os cenários para implementações .NET diferentes do .NET 5+.

Para obter mais informações, consulte Clusters de grafema.

Como instanciar um Rune

Há várias maneiras de obter uma instância Rune. Você pode usar um construtor para criar um Rune diretamente de:

  • Um ponto de código.

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

    Rune c = new Rune('a');
    
  • Um par suplementar char .

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

Todos os construtores lançam um ArgumentException se a entrada não representa um valor escalar Unicode válido.

Existem Rune.TryCreate métodos disponíveis para chamadores que não querem que exceções sejam lançadas em caso de falha.

Rune As instâncias também podem ser lidas a partir de sequências de entrada existentes. Por exemplo, dado um ReadOnlySpan<char> que representa dados em UTF-16, o método Rune.DecodeFromUtf16 retorna a primeira instância de Rune no início do segmento de entrada. O Rune.DecodeFromUtf8 método opera de forma semelhante, aceitando um parâmetro que representa dados ReadOnlySpan<byte> UTF-8. Existem métodos equivalentes para ler a partir do final do intervalo em vez do início do intervalo.

Consulta as propriedades de um Rune

Para obter o valor de ponto de código inteiro de uma Rune instância, use a Rune.Value propriedade.

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

Muitas das APIs estáticas disponíveis no char tipo também estão disponíveis no Rune tipo. Por exemplo, Rune.IsWhiteSpace e Rune.GetUnicodeCategory são equivalentes a Char.IsWhiteSpace e Char.GetUnicodeCategory métodos. Os Rune métodos lidam corretamente com pares substitutos.

O código de exemplo a seguir toma ReadOnlySpan<char> como entrada e remove, tanto do início quanto do fim do intervalo, todos os Rune que não sejam uma letra ou um dígito.

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

Existem algumas diferenças de API entre char e Rune. Por exemplo:

Converter a Rune para UTF-8 ou UTF-16

Como a Rune é um valor escalar Unicode, ele pode ser convertido em codificação UTF-8, UTF-16 ou UTF-32. O Rune tipo tem suporte interno para conversão para UTF-8 e UTF-16.

O Rune.EncodeToUtf16 converte uma Rune instância em char instâncias. Para consultar o número de instâncias que resultariam da conversão de char uma instância Rune para UTF-16, use a propriedade Rune.Utf16SequenceLength. Existem métodos semelhantes para a conversão UTF-8.

O exemplo a seguir converte uma Rune instância em uma char matriz. O código pressupõe que você tenha uma Rune instância na rune variável:

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

Como a string é uma sequência de caracteres UTF-16, o exemplo a seguir também converte uma Rune instância em UTF-16:

string theString = rune.ToString();

O exemplo a seguir converte uma Rune instância em uma UTF-8 matriz de bytes:

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

Os Rune.EncodeToUtf16 métodos e Rune.EncodeToUtf8 retornam o número real de elementos gravados. Eles lançam uma exceção se o buffer de destino for muito curto para conter o resultado. Há métodos de não-lançamento TryEncodeToUtf8 e TryEncodeToUtf16 também para chamadores que querem evitar exceções.

Runa no .NET vs. outros idiomas

O termo "runa" não está definido no padrão Unicode. O termo remonta à criação da UTF-8. Rob Pike e Ken Thompson estavam procurando um termo para descrever o que viria a ser conhecido como um ponto de código. Eles decidiram pelo termo "runa" e a posterior influência de Rob Pike na linguagem de programação Go ajudou a popularizar o termo.

No entanto, o tipo .NET Rune não é o equivalente ao tipo Go rune . Em Go, o rune tipo é um sinónimo para int32. Uma runa Go destina-se a representar um ponto de código Unicode, mas pode ser qualquer valor de 32 bits, incluindo pontos de código substitutos e valores que não são pontos de código Unicode legais.

Para tipos semelhantes em outras linguagens de programação, consulte o tipo primitivo char de Rust ou o tipo de Unicode.Scalar Swift, que representam valores escalares Unicode. Eles fornecem funcionalidade semelhante ao tipo Rune do .NET e proíbem a instanciação de valores que não são valores escalares Unicode legais.

Construtores

Name Descrição
Rune(Char, Char)

Cria um Rune a partir do par de substitutos UTF-16 fornecido.

Rune(Char)

Cria a Rune partir da unidade de código UTF-16 fornecida.

Rune(Int32)

Cria um Rune a partir do inteiro especificado de 32 bits que representa um valor escalar Unicode.

Rune(UInt32)

Cria um Rune a partir do inteiro não assinado de 32 bits especificado que representa um valor escalar Unicode.

Propriedades

Name Descrição
IsAscii

Obtém um valor que indica se o valor escalar associado a isto Rune está dentro do intervalo de codificação ASCII.

IsBmp

Obtém um valor que indica se o valor escalar associado a isto Rune está dentro do intervalo de codificação BMP.

Plane

Obtém o plano Unicode (0 a 16, inclusive) que contém este escalar.

ReplacementChar

Obtém uma Rune instância que representa o carácter de substituição Unicode U+FFFD.

Utf16SequenceLength

Obtém o comprimento em unidades de código (Char) da sequência UTF-16 necessária para representar este valor escalar.

Utf8SequenceLength

Obtém o comprimento em unidades de código da sequência UTF-8 necessário para representar este valor escalar.

Value

Obtém o valor escalar do Unicode como um inteiro.

Métodos

Name Descrição
CompareTo(Rune)

Compara a instância atual com a instância especificada Rune .

DecodeFromUtf16(ReadOnlySpan<Char>, Rune, Int32)

Descodifica o Rune no início do buffer de origem UTF-16 fornecido.

DecodeFromUtf8(ReadOnlySpan<Byte>, Rune, Int32)

Decodifica o Rune no início do buffer de origem UTF-8 fornecido.

DecodeLastFromUtf16(ReadOnlySpan<Char>, Rune, Int32)

Descodifica o Rune no final do buffer de origem UTF-16 fornecido.

DecodeLastFromUtf8(ReadOnlySpan<Byte>, Rune, Int32)

Descodifica o Rune no final do buffer de origem UTF-8 fornecido.

EncodeToUtf16(Span<Char>)

Codifica isto Rune num buffer de destino UTF-16.

EncodeToUtf8(Span<Byte>)

Codifica isto Rune num buffer de destino UTF-8.

Equals(Object)

Devolve um valor que indica se a instância atual e um objeto especificado são iguais.

Equals(Rune, StringComparison)

Representa um valor escalar Unicode ([ U+0000..U+D7FF ], inclusive; ou [ U+E000.. U+10FFFF ], inclusive).

Equals(Rune)

Devolve um valor que indica se a instância atual e uma runa especificada são iguais.

GetHashCode()

Devolve o código de hash para esta instância.

GetNumericValue(Rune)

Recebe o valor numérico associado à runa especificada.

GetRuneAt(String, Int32)

Obtém-se que Rune começa numa posição especificada numa corda.

GetUnicodeCategory(Rune)

Recebe a categoria Unicode associada à runa especificada.

IsControl(Rune)

Devolve um valor que indica se a runa especificada está categorizada como carácter de controlo.

IsDigit(Rune)

Devolve um valor que indica se a runa especificada está categorizada como um dígito decimal.

IsLetter(Rune)

Devolve um valor que indica se a runa especificada está categorizada como uma letra.

IsLetterOrDigit(Rune)

Devolve um valor que indica se a runa especificada está categorizada como letra ou dígito decimal.

IsLower(Rune)

Devolve um valor que indica se a runa especificada está categorizada como letra minúscula.

IsNumber(Rune)

Devolve um valor que indica se a runa especificada está categorizada como um número.

IsPunctuation(Rune)

Devolve um valor que indica se a runa especificada está categorizada como sinal de pontuação.

IsSeparator(Rune)

Devolve um valor que indica se a runa especificada está categorizada como carácter separador.

IsSymbol(Rune)

Devolve um valor que indica se a runa especificada está categorizada como um carácter simbólico.

IsUpper(Rune)

Devolve um valor que indica se a runa especificada está categorizada como letra maiúscula.

IsValid(Int32)

Devolve um valor que indica se um inteiro com assinatura de 32 bits representa um valor escalar Unicode válido; isto é, está no intervalo [ U+0000..U+D7FF ], inclusive; ou [U+E000.. U+10FFFF ], inclusive.

IsValid(UInt32)

Devolve um valor que indica se um inteiro não assinado de 32 bits representa um valor escalar Unicode válido; isto é, está no intervalo [ U+0000..U+D7FF ], inclusive, ou [ U+E000.. U+10FFFF ], inclusive.

IsWhiteSpace(Rune)

Devolve um valor que indica se a runa especificada está categorizada como um carácter de espaço em branco.

ToLower(Rune, CultureInfo)

Devolve uma cópia do especificado Rune convertido para minúsculas, usando as regras de carcaça da cultura especificada.

ToLowerInvariant(Rune)

Devolve uma cópia do Rune especificado convertido para minúsculas usando as regras de carcaça da cultura invariante.

ToString()

Devolve a representação da cadeia desta Rune instância.

ToUpper(Rune, CultureInfo)

Devolve uma cópia da convertida para maiúsculas especificada Rune , usando as regras de carcaça da cultura especificada.

ToUpperInvariant(Rune)

Devolve uma cópia do especificado Rune convertido para maiúsculas usando as regras de carcaça da cultura invariante.

TryCreate(Char, Char, Rune)

Tenta criar um Rune a partir do par de substitutos UTF-16 especificado e retorna um valor que indica se a operação foi bem-sucedida.

TryCreate(Char, Rune)

Tenta criar a Rune a partir de um carácter especificado e devolve um valor que indica se a operação teve sucesso.

TryCreate(Int32, Rune)

Tenta criar um Rune a partir de um inteiro com sinal especificado que represente um valor escalar Unicode.

TryCreate(UInt32, Rune)

Tenta criar um Rune a partir do inteiro não assinado de 32 bits especificado que represente um valor escalar Unicode.

TryEncodeToUtf16(Span<Char>, Int32)

Codifica isto Rune num buffer de destino codificado em UTF-16.

TryEncodeToUtf8(Span<Byte>, Int32)

Codifica isto Rune num buffer de destino codificado em UTF-8.

TryGetRuneAt(String, Int32, Rune)

Tenta obter o Rune que começa numa posição especificada numa cadeia e devolver um valor que indique se a operação teve sucesso.

Operadores

Name Descrição
Equality(Rune, Rune)

Devolve um valor que indica se duas Rune instâncias são iguais.

Explicit(Char to Rune)

Define uma conversão explícita de um carácter Unicode de 16 bits para um Rune.

Explicit(Int32 to Rune)

Define uma conversão explícita de um inteiro com sinal de 32 bits para um Rune.

Explicit(UInt32 to Rune)

Define uma conversão explícita de um inteiro sem sinal de 32 bits para um Rune.

GreaterThan(Rune, Rune)

Devolve um valor que indica se um especificado Rune é maior do que outro especificado Rune.

GreaterThanOrEqual(Rune, Rune)

Devolve um valor que indica se um especificado Rune é maior ou igual a outro especificado Rune.

Inequality(Rune, Rune)

Devolve um valor que indica se duas Rune instâncias têm valores diferentes.

LessThan(Rune, Rune)

Devolve um valor que indica se um especificado Rune é menor do que outro especificado Rune.

LessThanOrEqual(Rune, Rune)

Devolve um valor que indica se um especificado Rune é menor ou igual a outro especificado Rune.

Implementações de Interface Explícita

Name Descrição
IComparable.CompareTo(Object)

Compara a instância atual com o objeto especificado.

IFormattable.ToString(String, IFormatProvider)

Formata o valor da instância atual usando o formato especificado.

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

Tenta formatar o valor da instância atual no intervalo fornecido de caracteres.

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

Tenta formatar o valor da instância atual como UTF-8 no intervalo fornecido de bytes.

IUtf8SpanParsable<Rune>.Parse(ReadOnlySpan<Byte>, IFormatProvider)

Analisa um intervalo de caracteres UTF-8 num valor.

IUtf8SpanParsable<Rune>.TryParse(ReadOnlySpan<Byte>, IFormatProvider, Rune)

Representa um valor escalar Unicode ([ U+0000..U+D7FF ], inclusive; ou [ U+E000.. U+10FFFF ], inclusive).

Aplica-se a