Rune 構造体

定義

Unicode スカラー値 ([U+0000..U+D7FF]、包括、または [U+E000..U+10FFFF ]、両端を含む)。

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)
継承
実装

注釈

Rune インスタンスは Unicode スカラー値を表します。つまり、任意のコードポイントですが、サロゲート範囲 (U+D800..U+DFFF) を除きます。 型のコンストラクターと変換演算子は入力を検証するため、コンシューマーは基になる Rune インスタンスが整形式であると仮定して API を呼び出すことができます。

Unicode スカラー値、コード ポイント、サロゲート範囲、整形式の用語に慣れていない場合は、「 .NET での文字エンコードの概要」を参照してください。

ルーン タイプを使うタイミング

コードが次の場合は、 Rune 型の使用を検討してください。

  • Unicode スカラー値を必要とする API を呼び出す
  • サロゲート ペアを明示的に処理する

Unicode スカラー値を必要とする API

コードがcharまたはstring内のReadOnlySpan<char>インスタンスを反復処理する場合、一部の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 インスタンスがサロゲート コード ポイントであるためです。 1 つのサロゲート コード ポイントには、文字かどうかを判断するのに十分な情報がありません。

Runeではなくcharを使用するようにこのコードを変更すると、基本多言語プレーンの外部のコード ポイントでメソッドが正しく機能します。

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

サロゲート ペアを明示的に処理するコード

次のメソッドなど、サロゲート コード ポイントを明示的に操作する API をコードが呼び出す場合は、 Rune 型の使用を検討してください。

たとえば、次のメソッドには、サロゲート 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 一致を検索します
  • 既知の文字値で文字列を分割します

コードが次の場合、 Rune 型を使用すると正しくない結果が返される場合があります。

  • 内の表示文字数をカウントします。 string

厳密な char 一致を検索します

次のコードは、特定の文字を検索する string を反復処理し、最初の一致のインデックスを返します。 Runeを使用するためにこのコードを変更する必要はありません。コードは、1 つの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
}

文字列を既知のcharで分割する

次の例のように、 string.Split を呼び出し、 ' ' (スペース) や ',' (コンマ) などの区切り記号を使用するのが一般的です。

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

コードは単一のRuneで表される文字を探しているため、ここではcharを使用する必要はありません。

string 内の表示文字数をカウントします。

文字列内の Rune インスタンスの数が、文字列を表示するときに表示されるユーザーが認識できる文字の数と一致しない可能性があります。

Runeインスタンスは Unicode スカラー値を表しているため、Unicode テキストのセグメント化ガイドラインに従うコンポーネントでは、表示文字をカウントするための構成要素として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
    
  • 1つの char

    Rune c = new Rune('a');
    
  • サロゲート char ペア。

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

入力が有効な Unicode スカラー値を表していない場合、すべてのコンストラクターは ArgumentException をスローします。

エラー発生時に例外をスローしたくない呼び出し元には、 Rune.TryCreate メソッドを使用できます。

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.IsWhiteSpace メソッドと Char.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;
}

charRuneには、いくつかの API の違いがあります。 例えば次が挙げられます。

Runeを UTF-8 または UTF-16 に変換する

Runeは Unicode スカラー値であるため、UTF-8、UTF-16、または UTF-32 エンコードに変換できます。 Rune型には、UTF-8 および UTF-16 への変換が組み込まれています。

Rune.EncodeToUtf16は、Rune インスタンスを char インスタンスに変換します。 char インスタンスを UTF-16 に変換した結果として発生するRuneインスタンスの数を照会するには、Rune.Utf16SequenceLength プロパティを使用します。 UTF-8 変換にも同様のメソッドが存在します。

次の例では、 Rune インスタンスを char 配列に変換します。 このコードでは、Rune変数に rune インスタンスがあることを前提としています。

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

stringは UTF-16 文字のシーケンスであるため、次の例では、Rune インスタンスも UTF-16 に変換します。

string theString = rune.ToString();

次の例では、 Rune インスタンスを UTF-8 バイト配列に変換します。

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

Rune.EncodeToUtf16メソッドとRune.EncodeToUtf8 メソッドは、書き込まれた要素の実際の数を返します。 宛先バッファーが短すぎて結果を格納できない場合、例外がスローされます。 例外を回避する呼び出し元には、例外をスローしない TryEncodeToUtf8 メソッドと TryEncodeToUtf16 メソッドもあります。

.NET の Rune と他の言語の比較

"rune" という用語は、Unicode 標準では定義されていません。 この用語は UTF-8 の作成に遡ります。 Rob Pike と Ken Thompson は、最終的に何がコード ポイントとして知られるかを説明する用語を探していました。 彼らは「ルーン」という用語に落ち着き、後にGoプログラミング言語に対するロブ・パイクの影響が用語の普及に役立ちました。

ただし、.NET Rune 型は Go rune 型と同等ではありません。 Go では、rune 型は int32 での別名です。 Go ルーンは Unicode コード ポイントを表すことを目的としていますが、サロゲート コード ポイントや有効な Unicode コード ポイントではない値など、任意の 32 ビット値を指定できます。

他のプログラミング言語でも同様の型については、 Rust のプリミティブ char または Swift の Unicode.Scalarを参照してください。どちらも Unicode スカラー値を表します。 これらは、.NET の Rune 型に似た機能を提供し、有効な Unicode スカラー値でない値のインスタンス化を禁止します。

コンストラクター

名前 説明
Rune(Char, Char)

指定された UTF-16 サロゲート ペアから Rune を作成します。

Rune(Char)

指定された UTF-16 コード ユニットから Rune を作成します。

Rune(Int32)

Unicode スカラー値を表す指定した 32 ビット整数から Rune を作成します。

Rune(UInt32)

Unicode スカラー値を表す指定した 32 ビット符号なし整数から Rune を作成します。

プロパティ

名前 説明
IsAscii

この Rune に関連付けられているスカラー値が ASCII エンコード範囲内にあるかどうかを示す値を取得します。

IsBmp

この Rune に関連付けられているスカラー値が BMP エンコード範囲内にあるかどうかを示す値を取得します。

Plane

このスカラーを含む Unicode 平面 (0 ~ 16 を含む) を取得します。

ReplacementChar

Unicode 置換文字 U+FFFD を表す Rune インスタンスを取得します。

Utf16SequenceLength

このスカラー値を表すために必要な UTF-16 シーケンスのコード単位 (Char) の長さを取得します。

Utf8SequenceLength

このスカラー値を表すために必要な UTF-8 シーケンスのコード単位の長さを取得します。

Value

Unicode スカラー値を整数として取得します。

メソッド

名前 説明
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, StringComparison)

Unicode スカラー値 ([U+0000..U+D7FF]、包括、または [U+E000..U+10FFFF ]、両端を含む)。

Equals(Rune)

現在のインスタンスと指定したルーンが等しいかどうかを示す値を返します。

GetHashCode()

このインスタンスのハッシュ コードを返します。

GetNumericValue(Rune)

指定したルーンに関連付けられた数値を取得します。

GetRuneAt(String, Int32)

文字列内の指定した位置から始まる Rune を取得します。

GetUnicodeCategory(Rune)

指定したルーンに関連付けられている Unicode カテゴリを取得します。

IsControl(Rune)

指定したルーンがコントロール文字として分類されているかどうかを示す値を返します。

IsDigit(Rune)

指定したルーンが 10 進数字として分類されているかどうかを示す値を返します。

IsLetter(Rune)

指定したルーンが文字として分類されているかどうかを示す値を返します。

IsLetterOrDigit(Rune)

指定したルーンが文字または 10 進数字として分類されるかどうかを示す値を返します。

IsLower(Rune)

指定したルーンが小文字として分類されているかどうかを示す値を返します。

IsNumber(Rune)

指定したルーンが数値として分類されているかどうかを示す値を返します。

IsPunctuation(Rune)

指定したルーンが句読点として分類されているかどうかを示す値を返します。

IsSeparator(Rune)

指定したルーンが区切り文字として分類されているかどうかを示す値を返します。

IsSymbol(Rune)

指定したルーンがシンボル文字として分類されているかどうかを示す値を返します。

IsUpper(Rune)

指定したルーンが大文字として分類されているかどうかを示す値を返します。

IsValid(Int32)

32 ビット符号付き整数が有効な Unicode スカラー値を表すかどうかを示す値を返します。つまり、[U+0000..U+D7FF] の範囲内です。または [ U+E000..U+10FFFF ]。両端を含みます。

IsValid(UInt32)

32 ビット符号なし整数が有効な Unicode スカラー値を表すかどうかを示す値を返します。つまり、範囲は [U+0000..U+D7FF]、包括、または [U+E000..U+10FFFF ]。両端を含みます。

IsWhiteSpace(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)

Unicode スカラー値を表す指定した符号付き整数から Rune の作成を試みます。

TryCreate(UInt32, Rune)

Unicode スカラー値を表す、指定した 32 ビット符号なし整数から Rune の作成を試みます。

TryEncodeToUtf16(Span<Char>, Int32)

この Rune を UTF-16 でエンコードされた宛先バッファーにエンコードします。

TryEncodeToUtf8(Span<Byte>, Int32)

この Rune を UTF-8 でエンコードされた宛先バッファーにエンコードします。

TryGetRuneAt(String, Int32, Rune)

文字列内の指定した位置から始まる Rune を取得し、操作が成功したかどうかを示す値を返します。

演算子

名前 説明
Equality(Rune, Rune)

2 つの Rune インスタンスが等しいかどうかを示す値を返します。

Explicit(Char to Rune)

16 ビット Unicode 文字から 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)

2 つの 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)

現在のインスタンスの値を指定された文字スパンに書式設定しようとします。

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

現在のインスタンスの値を UTF-8 として指定されたバイトスパンに書式設定しようとします。

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

UTF-8 文字のスパンを値に解析します。

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

Unicode スカラー値 ([U+0000..U+D7FF]、包括、または [U+E000..U+10FFFF ]、両端を含む)。

適用対象