Rune 구조체

정의

유니코드 스칼라 값([ U+0000..U+D7FF ], 포함 또는 [ U+E000..U+10FFFF ], 포함)을 나타냅니다.

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<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<System.Text.Rune>, IEquatable<System.Text.Rune>
type Rune = struct
type Rune = struct
    interface ISpanFormattable
    interface IFormattable
type Rune = struct
    interface IFormattable
    interface ISpanFormattable
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(Of Rune), IEquatable(Of Rune)
상속
구현

설명

인스턴스는 Rune 서로게이트 범위를 제외한 모든 코드 포인트(U+D800.)를 의미하는 유니코드 스칼라 값을 나타냅니다. U+DFFF). 형식의 생성자 및 변환 연산자는 입력의 유효성을 검사하므로 소비자는 기본 인스턴스가 올바른 형식이라고 가정하여 API를 Rune 호출할 수 있습니다.

유니코드 스칼라 값, 코드 포인트, 서로게이트 범위 및 잘 구성된 용어에 익숙하지 않은 경우 .NET의 문자 인코딩 소개를 참조하세요.

다음 섹션에서는 다음을 설명합니다.

Rune 형식을 사용해야 하는 경우

코드가 다음과 같은 경우 형식을 Rune 사용하는 것이 좋습니다.

  • 유니코드 스칼라 값이 필요한 API 호출
  • 서로게이트 쌍을 명시적으로 처리합니다.

유니코드 스칼라 값이 필요한 API

코드가 char 또는 ReadOnlySpan<char>의 인스턴스를 string 반복하는 경우 일부 char 메서드는 서로게이트 범위에 있는 인스턴스에서 char 제대로 작동하지 않습니다. 예를 들어 다음 API는 스칼라 값 char 이 올바르게 작동해야 합니다.

다음 예제에서는 인스턴스가 서로게이트 코드 포인트인 경우 char 제대로 작동하지 않는 코드를 보여 줍니다.

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

다음은 와 함께 작동하는 동등한 코드입니다.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;
}

앞의 코드는 영어와 같은 일부 언어에서 올바르게 작동합니다.

CountLettersInString("Hello")
// Returns 5

그러나 Osage와 같은 기본 다국어 평면 외부의 언어에서는 제대로 작동하지 않습니다.

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

이 메서드가 Osage 텍스트에 대해 잘못된 결과를 반환하는 이유는 Osage 문자의 char 인스턴스가 서로게이트 코드 포인트이기 때문입니다. 단일 서로게이트 코드 포인트에 문자인지 확인할 수 있는 충분한 정보가 없습니다.

대신 char를 사용하도록 Rune 이 코드를 변경하는 경우 메서드는 기본 다국어 평면 외부의 코드 포인트에서 올바르게 작동합니다.

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

다음은 와 함께 작동하는 동등한 코드입니다.ReadOnlySpan<char>

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

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

    return letterCount;
}

앞의 코드는 Osage 문자를 올바르게 계산합니다.

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

서로게이트 쌍을 명시적으로 처리하는 코드

코드가 Rune 다음 메서드와 같이 서로게이트 코드 지점에서 명시적으로 작동하는 API를 호출하는 경우 형식을 사용하는 것이 좋습니다.

예를 들어 다음 메서드에는 서로게이트 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.");
        }
    }
}

이러한 코드는 다음 예제와 같이 를 사용하는 Rune경우 더 간단합니다.

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

Rune를 사용하지 않는 경우

코드가 다음과 같은 경우 형식을 Rune 사용할 필요가 없습니다.

  • 정확한 일치 항목을 찾습니다.char
  • 알려진 char 값에 문자열을 분할합니다.

형식을 사용하면 코드가 Rune 다음과 같은 경우 잘못된 결과를 반환할 수 있습니다.

  • 의 표시 문자 수를 계산합니다. string

정확한 char 일치 항목 찾기

다음 코드는 특정 문자를 찾고 첫 번째 일치 항목의 인덱스를 반환하는 을 반복 string 합니다. 코드가 단일 char로 표현되는 문자를 찾고 있으므로 를 사용하도록 Rune이 코드를 변경할 필요가 없습니다.

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
}

알려진 에서 문자열 분할 char

다음 예제와 같이 (공백) 또는 ',' (쉼표)와 같은 ' ' 구분 기호를 호출 string.Split 하고 사용하는 것이 일반적입니다.

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

코드가 단일 char로 표현되는 문자를 찾고 있으므로 여기서 를 사용할 Rune 필요가 없습니다.

의 표시 문자 수 계산 string

문자열의 Rune 인스턴스 수가 문자열을 표시할 때 표시되는 사용자 인식 가능 문자 수와 일치하지 않을 수 있습니다.

인스턴스는 유니코드 스칼라 값을 나타내기 때문에 Rune유니코드 텍스트 구분 지침을 따르는 구성 요소는 표시 문자를 계산하기 위한 구성 요소로 사용할 Rune 수 있습니다.

형식을 StringInfo 사용하여 표시 문자 수를 계산할 수 있지만 .NET 5 이상 이외의 .NET 구현에 대한 모든 시나리오에서는 올바르게 계산되지 않습니다.

자세한 내용은 Grapheme 클러스터를 참조하세요.

를 인스턴스화하는 방법 Rune

인스턴스를 가져오는 방법에는 여러 가지가 있습니다 Rune . 생성자를 사용하여 다음에서 직접 를 Rune 만들 수 있습니다.

  • 코드 포인트입니다.

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

    Rune c = new Rune('a');
    
  • 서로게이트 char 쌍입니다.

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

입력이 유효한 유니코드 스칼라 값을 나타내지 않으면 모든 생성자가 을 throw ArgumentException 합니다.

Rune.TryCreate 실패 시 예외를 throw하지 않으려는 호출자에게 사용할 수 있는 메서드가 있습니다.

Rune 기존 입력 시퀀스에서 인스턴스를 읽을 수도 있습니다. 예를 들어 UTF-16 데이터를 나타내는 가 지정된 경우 ReadOnlySpan<char> 메서드는 Rune.DecodeFromUtf16 입력 범위의 시작 부분에 첫 번째 Rune 인스턴스를 반환합니다. 메서드는 Rune.DecodeFromUtf8 UTF-8 데이터를 나타내는 매개 변수를 ReadOnlySpan<byte> 수락하여 유사하게 작동합니다. 범위의 시작이 아닌 범위 끝에서 읽는 동일한 메서드가 있습니다.

의 쿼리 속성 Rune

인스턴스의 정수 코드 포인트 값을 Rune 얻으려면 속성을 사용합니다 Rune.Value .

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

형식에서 char 사용할 수 있는 많은 정적 API도 형식에서 Rune 사용할 수 있습니다. 예를 들어 및 Rune.IsWhiteSpaceRune.GetUnicodeCategory 는 및 메서드와 Char.IsWhiteSpaceChar.GetUnicodeCategory 동일합니다. 메서드는 Rune 서로게이트 쌍을 올바르게 처리합니다.

다음 예제 코드는 를 입력으로 사용하고 ReadOnlySpan<char> 문자나 숫자가 아닌 모든 Rune 범위의 시작과 끝에서 트리밍합니다.

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

Rune사이에 char 는 몇 가지 API 차이점이 있습니다. 예를 들면 다음과 같습니다.

Rune UTF-8 또는 UTF-16으로 변환

Rune 는 유니코드 스칼라 값이므로 UTF-8, UTF-16 또는 UTF-32 인코딩으로 변환할 수 있습니다. 형식은 Rune UTF-8 및 UTF-16으로의 변환을 기본적으로 지원합니다.

Rune.EncodeToUtf16 인스턴스를 인스턴스로 Runechar 변환합니다. 인스턴스를 UTF-16으로 변환하여 Rune 발생하는 인스턴스 수를 char 쿼리하려면 속성을 사용합니다Rune.Utf16SequenceLength. UTF-8 변환에 대해 유사한 메서드가 있습니다.

다음 예제에서는 인스턴스를 Rune 배열로 변환합니다 char . 코드는 변수에 인스턴스가 Rune 있다고 가정합니다.rune

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

string UTF-16 문자 시퀀스이므로 다음 예제에서는 인스턴스를 UTF-16으로 변환합니다 Rune .

string theString = rune.ToString();

다음 예제에서는 인스턴스를 Rune 바이트 배열로 UTF-8 변환합니다.

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

Rune.EncodeToUtf8 메서드는 Rune.EncodeToUtf16 작성된 실제 요소 수를 반환합니다. 대상 버퍼가 너무 짧아 결과를 포함할 수 없는 경우 예외를 throw합니다. 예외를 TryEncodeToUtf8 방지하려는 호출자에 대한 비 throw 및 TryEncodeToUtf16 메서드도 있습니다.

.NET 및 기타 언어의 Rune

"rune"라는 용어는 유니코드 표준에 정의되어 있지 않습니다. 이 용어는 UTF-8 생성으로 거슬러 올라갑니다. 롭 파이크와 켄 톰슨은 결국 코드 포인트로 알려질 것을 설명하는 용어를 찾고 있었다. 그들은 "rune"이라는 용어에 정착했고, Rob Pike가 나중에 Go 프로그래밍 언어에 미치는 영향은 이 용어를 대중화하는 데 도움이 되었습니다.

그러나 .NET Rune 형식은 Go rune 형식과 동일하지 않습니다. Go에서 형식은 rune별칭 int32입니다. Go rune은 유니코드 코드 포인트를 나타내기 위한 것이지만 서로게이트 코드 포인트와 합법적인 유니코드 코드 포인트가 아닌 값을 포함하여 32비트 값일 수 있습니다.

다른 프로그래밍 언어의 유사한 형식은 Rust의 기본 char 형식 또는 Swift 형식Unicode.Scalar을 참조하세요. 둘 다 유니코드 스칼라 값을 나타냅니다. 이와 유사한 기능을 제공합니다. NET의 Rune 형식이며, 합법적인 유니코드 스칼라 값이 아닌 값의 인스턴스화를 허용하지 않습니다.

생성자

Rune(Char)

제공된 UTF-16 코드 단위에서 Rune을 만듭니다.

Rune(Char, Char)

제공된 UTF-16 서로게이트 쌍에서 Rune을 만듭니다.

Rune(Int32)

유니코드 스칼라 값을 나타내는 지정된 32비트 정수에서 Rune를 만듭니다.

Rune(UInt32)

유니코드 스칼라 값을 나타내는 지정된 32비트 부호 없는 정수에서 Rune를 만듭니다.

속성

IsAscii

Rune과 연결된 스칼라 값이 ASCII 인코딩 범위에 포함되어 있는지 표시하는 값을 가져옵니다.

IsBmp

Rune과 연결된 스칼라 값이 BMP 인코딩 범위에 포함되어 있는지 표시하는 값을 가져옵니다.

Plane

이 스칼라를 포함하는 유니코드 평면(0 ~ 16, 포함)을 가져옵니다.

ReplacementChar

유니코드 대체 문자 U+FFFD를 나타내는 Rune 인스턴스를 가져옵니다.

Utf16SequenceLength

이 스칼라 값을 나타내는 데 필요한 UTF-16 시퀀스의 코드 단위(Char)의 길이를 가져옵니다.

Utf8SequenceLength

이 스칼라 값을 나타내는 데 필요한 UTF-8 시퀀스의 코드 단위의 길이를 가져옵니다.

Value

유니코드 스칼라 값을 정수로 가져옵니다.

메서드

CompareTo(Rune)

현재 인스턴스를 지정된 Rune 인스턴스와 비교합니다.

DecodeFromUtf16(ReadOnlySpan<Char>, Rune, Int32)

제공된 UTF-16 소스 버퍼의 시작 부분에서 Rune을 디코딩합니다.

DecodeFromUtf8(ReadOnlySpan<Byte>, Rune, Int32)

제공된 UTF-8 소스 버퍼의 시작 부분에서 Rune을 디코딩합니다.

DecodeLastFromUtf16(ReadOnlySpan<Char>, Rune, Int32)

제공된 UTF-16 소스 버퍼의 끝부분에서 Rune을 디코딩합니다.

DecodeLastFromUtf8(ReadOnlySpan<Byte>, Rune, Int32)

제공된 UTF-8 소스 버퍼의 끝 부분에서 Rune을 디코딩합니다.

EncodeToUtf16(Span<Char>)

Rune을 UTF-16 대상 버퍼로 인코딩합니다.

EncodeToUtf8(Span<Byte>)

Rune을 UTF-8 대상 버퍼로 인코딩합니다.

Equals(Object)

현재 인스턴스와 지정된 개체가 같은지 여부를 나타내는 값을 반환합니다.

Equals(Rune)

현재 인스턴스와 지정된 rune이 같은지 여부를 나타내는 값을 반환합니다.

GetHashCode()

이 인스턴스의 해시 코드를 반환합니다.

GetNumericValue(Rune)

지정된 rune과 연결된 숫자 값을 가져옵니다.

GetRuneAt(String, Int32)

문자열의 지정된 위치에서 시작하는 Rune을 가져옵니다.

GetUnicodeCategory(Rune)

지정된 rune에 연결된 유니코드 범주를 가져옵니다.

IsControl(Rune)

지정된 rune을 제어 문자로 분류하는지 표시하는 값을 반환합니다.

IsDigit(Rune)

지정된 rune을 10진수로 분류하는지 표시하는 값을 반환합니다.

IsLetter(Rune)

지정된 rune을 문자로 분류하는지 표시하는 값을 반환합니다.

IsLetterOrDigit(Rune)

지정된 rune을 문자로 분류할지 아니면 10진수로 분류할지 표시하는 값을 반환합니다.

IsLower(Rune)

지정된 rune을 소문자로 분류하는지 표시하는 값을 반환합니다.

IsNumber(Rune)

지정된 rune을 숫자로 분류하는지 표시하는 값을 반환합니다.

IsPunctuation(Rune)

지정된 rune을 구두점으로 분류하는지 표시하는 값을 반환합니다.

IsSeparator(Rune)

지정된 rune을 구분 문자로 분류하는지 표시하는 값을 반환합니다.

IsSymbol(Rune)

지정된 rune을 기호 문자로 분류하는지 표시하는 값을 반환합니다.

IsUpper(Rune)

지정된 rune을 대문자로 분류하는지 표시하는 값을 반환합니다.

IsValid(Int32)

32비트 부호 있는 정수가 올바른 유니코드 스칼라 값, 즉 [ U+0000..U+D7FF ](포함) 또는 [ U+E000..U+10FFFF ](포함) 범위에 있는지 나타내는 값을 반환합니다.

IsValid(UInt32)

32비트 부호 없는 정수가 올바른 유니코드 스칼라 값, 즉 [ U+0000..U+D7FF ](포함) 또는 [ U+E000..U+10FFFF ](포함) 범위에 있는지 나타내는 값을 반환합니다.

IsWhiteSpace(Rune)

지정된 rune을 공백 문자로 분류하는지 표시하는 값을 반환합니다.

ToLower(Rune, CultureInfo)

지정한 문화권의 대/소문자 규칙을 사용하여 소문자로 변환되는 지정된 Rune의 복사본을 반환합니다.

ToLowerInvariant(Rune)

고정 문화권의 대/소문자 규칙을 사용하여 소문자로 변환된 지정된 Rune의 복사본을 반환합니다.

ToString()

Rune 인스턴스의 문자열 표현을 반환합니다.

ToUpper(Rune, CultureInfo)

고정 문화권의 대/소문자 규칙을 사용하여 대문자로 변환되는 지정된 Rune의 복사본을 반환합니다.

ToUpperInvariant(Rune)

고정 문화권의 대/소문자 규칙을 사용하여 대문자로 변환된 지정된 Rune의 복사본을 반환합니다.

TryCreate(Char, Char, Rune)

지정된 UTF-16 서로게이트 쌍에서 Rune을 만들고 작업이 성공했는지 나타내는 값을 반환합니다.

TryCreate(Char, Rune)

지정된 문자에서 Rune을 만들려고 시도하며 작업이 성공했는지 나타내는 값을 반환합니다.

TryCreate(Int32, Rune)

유니코드 스칼라 값을 나타내는 지정된 부호 있는 정수에서 Rune을 만듭니다.

TryCreate(UInt32, Rune)

유니코드 스칼라 값을 나타내는 지정된 32비트 부호 없는 정수에서 Rune을 만듭니다.

TryEncodeToUtf16(Span<Char>, Int32)

Rune을 UTF-16으로 인코딩된 대상 버퍼로 인코딩합니다.

TryEncodeToUtf8(Span<Byte>, Int32)

Rune을 UTF-8로 인코딩된 대상 버퍼로 인코딩합니다.

TryGetRuneAt(String, Int32, Rune)

문자열의 지정된 위치에서 시작하는 Rune을 가져오고 작업에 성공했는지 나타내는 값을 반환합니다.

연산자

Equality(Rune, Rune)

Rune 인스턴스가 같은지 여부를 나타내는 값을 반환합니다.

Explicit(Char to Rune)

16비트 유니코드 문자를 Rune로 변환하는 명시적 변환을 정의합니다.

Explicit(Int32 to Rune)

32비트 부호 있는 정수를 Rune로 변환하는 명시적 변환을 정의합니다.

Explicit(UInt32 to Rune)

32비트 부호 없는 정수를 Rune로 변환하는 명시적 변환을 정의합니다.

GreaterThan(Rune, Rune)

지정된 Rune이 지정된 다른 Rune보다 큰지 여부를 나타내는 값을 반환합니다.

GreaterThanOrEqual(Rune, Rune)

지정된 Rune이 지정된 다른 Rune보다 크거나 같은지 여부를 나타내는 값을 반환합니다.

Inequality(Rune, Rune)

Rune 인스턴스의 값이 다른지 여부를 나타내는 값을 반환합니다.

LessThan(Rune, Rune)

지정된 Rune이 지정된 다른 Rune보다 작은지 여부를 나타내는 값을 반환합니다.

LessThanOrEqual(Rune, Rune)

지정된 Rune이 지정된 다른 Rune보다 작거나 같은지 여부를 나타내는 값을 반환합니다.

명시적 인터페이스 구현

IComparable.CompareTo(Object)

현재 인스턴스를 지정된 개체와 비교합니다.

IFormattable.ToString(String, IFormatProvider)

지정된 형식을 사용하여 현재 인스턴스 값의 형식을 지정합니다.

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

현재 인스턴스의 값을 제공된 문자 범위로 서식을 지정하려고 시도합니다.

적용 대상