Runtime: System.Rune ์†Œ๊ฐœ

์— ๋งŒ๋“  2017๋…„ 09์›” 16์ผ  ยท  106์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: dotnet/runtime

์—ฌ๊ธฐ ํ† ๋ก ์—์„œ ์˜๊ฐ์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค.

https://github.com/dotnet/corefxlab/issues/1751

.NET์ด ์œ ๋‹ˆ์ฝ”๋“œ ์ง€์›๊ณผ ํ•จ๊ป˜ ์ง๋ฉดํ•œ ๋ฌธ์ œ ์ค‘ ํ•˜๋‚˜๋Š” ํ˜„์žฌ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋””์ž์ธ์— ๋ฟŒ๋ฆฌ๋ฅผ ๋‘๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. .NET์—์„œ ๋ฌธ์ž๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ 16๋น„ํŠธ ๊ฐ’์ธ System.Char ๋กœ ์œ ๋‹ˆ์ฝ”๋“œ ๊ฐ’์„ ๋‚˜ํƒ€๋‚ด๊ธฐ์— ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

.NET ๊ฐœ๋ฐœ์ž๋Š” ์‹ ๋น„ํ•œ ๋Œ€๋ฆฌ ์Œ์— ๋Œ€ํ•ด ๋ฐฐ์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

https://msdn.microsoft.com/en-us/library/xcwwfbb8 (v=vs.110).aspx

๊ฐœ๋ฐœ์ž๋Š” ์ด ์ง€์›์„ ๊ฑฐ์˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„ ์œ ๋‹ˆ์ฝ”๋“œ์— ์ต์ˆ™ํ•˜์ง€ ์•Š๊ณ  .NET์ด ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์€ ๊ณ ์‚ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

32๋น„ํŠธ ์ •์ˆ˜๋กœ ์ง€์›๋˜๊ณ  codePoint์— ํ•ด๋‹นํ•˜๋ฉฐ C#์—์„œ ํ•ด๋‹น rune ์œ ํ˜•์„ ์ด ์œ ํ˜•์˜ ๋ณ„์นญ์œผ๋กœ ํ‘œ์‹œํ•˜๋Š” System.Rune ๋ฅผ ๋„์ž…ํ•  ๊ฒƒ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.

rune ๋Š” char ์˜ ๊ธฐ๋ณธ ๋Œ€์ฒดํ’ˆ์ด ๋˜๋ฉฐ .NET์—์„œ ์ ์ ˆํ•œ ์œ ๋‹ˆ์ฝ”๋“œ ๋ฐ ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ๊ธฐ์ดˆ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฆ„์ด rune์ธ ์ด์œ ๋Š” Go์—์„œ ์˜๊ฐ์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค.

https://blog.golang.org/strings

"์ฝ”๋“œ ํฌ์ธํŠธ, ์บ๋ฆญํ„ฐ ๋ฐ ๋ฃฌ" ์„น์…˜์— ์„ค๋ช…์ด ์ œ๊ณต๋˜๋ฉฐ ์งง์€ ๋ฒ„์ „์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

"์ฝ”๋“œ ํฌ์ธํŠธ"๋Š” ์•ฝ๊ฐ„์˜ ์ž…์œผ๋กœ, ๊ทธ๋ž˜์„œ Go๋Š” ๊ฐœ๋…์— ๋Œ€ํ•œ ๋” ์งง์€ ์šฉ์–ด์ธ ๋ฃฌ์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ์ด ์šฉ์–ด๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ์†Œ์Šค ์ฝ”๋“œ์— ๋‚˜ํƒ€๋‚˜๋ฉฐ "์ฝ”๋“œ ํฌ์ธํŠธ"์™€ ์ •ํ™•ํžˆ ๋™์ผํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๋ฉฐ ํ•œ ๊ฐ€์ง€ ํฅ๋ฏธ๋กœ์šด ์ถ”๊ฐ€ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ ์ด์ œ ์—ฌ๊ธฐ์— System.Rune ๊ตฌํ˜„์ด ์žˆ์Šต๋‹ˆ๋‹ค.

https://github.com/migueldeicaza/NStack/blob/master/NStack/unicode/Rune.cs

๋‹ค์Œ API ์‚ฌ์šฉ:

public struct Rune {

    public Rune (uint rune);
    public Rune (char ch);

    public static ValueTuple<Rune,int> DecodeLastRune (byte [] buffer, int end);
    public static ValueTuple<Rune,int> DecodeLastRune (NStack.ustring str, int end);
    public static ValueTuple<Rune,int> DecodeRune (byte [] buffer, int start, int n);
    public static ValueTuple<Rune,int> DecodeRune (NStack.ustring str, int start, int n);
    public static int EncodeRune (Rune rune, byte [] dest, int offset);
    public static bool FullRune (byte [] p);
    public static bool FullRune (NStack.ustring str);
    public static int InvalidIndex (byte [] buffer);
    public static int InvalidIndex (NStack.ustring str);
    public static bool IsControl (Rune rune);
    public static bool IsDigit (Rune rune);
    public static bool IsGraphic (Rune rune);
    public static bool IsLetter (Rune rune);
    public static bool IsLower (Rune rune);
    public static bool IsMark (Rune rune);
    public static bool IsNumber (Rune rune);
    public static bool IsPrint (Rune rune);
    public static bool IsPunctuation (Rune rune);
    public static bool IsSpace (Rune rune);
    public static bool IsSymbol (Rune rune);
    public static bool IsTitle (Rune rune);
    public static bool IsUpper (Rune rune);
    public static int RuneCount (byte [] buffer, int offset, int count);
    public static int RuneCount (NStack.ustring str);
    public static int RuneLen (Rune rune);
    public static Rune SimpleFold (Rune rune);
    public static Rune To (Case toCase, Rune rune);
    public static Rune ToLower (Rune rune);
    public static Rune ToTitle (Rune rune);
    public static Rune ToUpper (Rune rune);
    public static bool Valid (byte [] buffer);
    public static bool Valid (NStack.ustring str);
    public static bool ValidRune (Rune rune);
    public override bool Equals (object obj);

    [System.Runtime.ConstrainedExecution.ReliabilityContractAttribute((System.Runtime.ConstrainedExecution.Consistency)3, (System.Runtime.ConstrainedExecution.Cer)2)]
    protected virtual void Finalize ();
    public override int GetHashCode ();
    public Type GetType ();
    protected object MemberwiseClone ();
    public override string ToString ();

    public static implicit operator uint (Rune rune);
    public static implicit operator Rune (char ch);
    public static implicit operator Rune (uint value);

    public bool IsValid {
        get;
    }

    public static Rune Error;
    public static Rune MaxRune;
    public const byte RuneSelf = 128;
    public static Rune ReplacementChar;
    public const int Utf8Max = 4;

    public enum Case {
        Upper,
        Lower,
        Title
    }
}

์•Œ๋ ค์ง„ ๋ฌธ์ œ ์—…๋ฐ์ดํŠธ

  • [x] ์œ„์˜ ์ผ๋ถ€ API๋Š” ๋‹จ์œ„๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋ฃฌ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • [ ] IComparable ์ œํ’ˆ๊ตฐ ๊ตฌํ˜„ ํ•„์š”
  • [ ] RuneCount/RuneLen์€ ๋” ๋‚˜์€ ์ด๋ฆ„์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”(์•„๋งˆ๋„ Utf8BytesNeeded?)
  • [ ] ์œ„์˜ "ustring" API๋Š” ๋‚ด UTF8 API๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์‹ค์ œ๋กœ API์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹ˆ์ง€๋งŒ ๊ทธ ์ค‘ ์ผ๋ถ€์— System.String ๋˜๋Š” Utf8String์— ๋Œ€ํ•œ ๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ ์žˆ๋Š”์ง€ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
api-needs-work area-System.Runtime up-for-grabs

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋‚˜๋Š” ์›๋ž˜ ๋ฌธ์ œ์—์„œ ๊ทธ๊ฒƒ์„ ๋งํ–ˆ๊ณ  ๋‹ค์‹œ ๋งํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๋ฌธ๊ตฌ๊ฐ€ ๋งˆ์Œ์— ๋“ค์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ‘œ์ค€์ด ๋งํ•˜๋Š” ๊ฒƒ์„ ํฌ๊ธฐํ•˜๋Š” ๊ฒƒ์€ ํ•ด๊ฒฐ๋˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ๊ฒƒ์ด๋ฉฐ, ์œ ๋‹ˆ์ฝ”๋“œ์— ๋ฃฌ ์ฝ”๋“œ ํŽ˜์ด์ง€๊ฐ€ ์žˆ๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ ๋” ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ๋ฟ์ž…๋‹ˆ๋‹ค.

์ด๋ฆ„์ด ์ž˜๋ชป๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  106 ๋Œ“๊ธ€

๋ฉ”๋ชจ๋ฆฌ ๋‚ด ํ‘œํ˜„์ด 32๋น„ํŠธ ๊ฐœ์ฒด์˜ ๋ฌธ์ž์—ด์ด๊ฑฐ๋‚˜ ์ฆ‰์„์—์„œ ๋ฒˆ์—ญ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•˜์‹ญ๋‹ˆ๊นŒ? ์ „์ž๋ผ๋ฉด ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋‘ ๋ฐฐ๋กœ ๋Š˜์–ด๋‚˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ํ›„์ž์˜ ๊ฒฝ์šฐ ์„ฑ๋Šฅ์— ์–ด๋–ค ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๊นŒ?

ํŠน์ • ์œ ๋‹ˆ์ฝ”๋“œ ์ง€์› ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋”ฐ๋ผ ์œ ๋‹ˆ์ฝ”๋“œ ๊ด€๋ จ ๊ธฐ์ˆ ์„ ๋ช…๋ช…ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์€ ์ƒ๊ฐ์ž…๋‹ˆ๊นŒ?

๋‚ด ์ƒ๊ฐ์— ์ œ์•ˆ(๊ทธ๋ฆฌ๊ณ  ์•„๋งˆ๋„ ๋” ๋ช…์‹œ์ ์ด์–ด์•ผ ํ•  ํ•„์š”๊ฐ€ ์žˆ์Œ)์€ ๋ฌธ์ž์—ด์˜ ๋ฉ”๋ชจ๋ฆฌ ๋‚ด ํ‘œํ˜„์ด ์ „ํ˜€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Rune ์œ ํ˜•์€ ๊ณ ์œ ํ•œ ๊ฐœ๋ณ„ 21๋น„ํŠธ ์ฝ”๋“œ ํฌ์ธํŠธ(32๋น„ํŠธ int๋กœ ์ €์žฅ๋จ)๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ฝ”๋“œ ํฌ์ธํŠธ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ฉ”์„œ๋“œ ๋Š” ์ž ์žฌ์ ์œผ๋กœ Rune ๋ฅผ ๋Œ€์‹  ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. string ์—๋Š” Rune ๋ฅผ ์—ด๊ฑฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์— ๋Œ€ํ•ด ํ•ฉ์˜๋ฅผ ์–ป์–ด์•ผ ํ•  ๋ช‡ ๊ฐ€์ง€ ๋ถ„๋ช…ํ•œ ์ ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

  1. ํ˜„์žฌ ๋ฉ”์„œ๋“œ์ฒ˜๋Ÿผ Int32 ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค Rune ์œ ํ˜•์„ ๋งŒ๋“œ๋Š” ๋ฐ ์ค‘์š”ํ•œ ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?
  2. "๋ฃฌ"์ด๋ผ๋Š” ๋‹จ์–ด๊ฐ€ ์‹ค์ œ๋กœ ์ข‹์€ ์„ ํƒ์ž…๋‹ˆ๊นŒ?

(1)์— ๋‹ตํ•˜๋ ค๋ฉด $#$ Int32 Rune ์ด ์–ด๋–ป๊ฒŒ ๋…ธ์ถœ๋˜๋Š”์ง€, ์–ด๋–ค ๋ฉ”์„œ๋“œ๊ฐ€ ์ด๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•˜๋Š”์ง€ ๋“ฑ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  Int32 .

(2)์— ๊ด€ํ•ด์„œ๋Š” ๋‚˜ ์ž์‹ ์ด ์กฐ๊ธˆ ๋ง์„ค์—ฌ์ง„๋‹ค. "๋ฃฌ"์€ ์˜์–ด๋กœ ๋œ ์ผ์ข…์˜ ๋‚œํ•ดํ•œ ๋‹จ์–ด์ด๋ฉฐ ์ด ๋ฌธ๋งฅ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ์žˆ์–ด ๋ช‡ ๊ฐ€์ง€ ํŠน์ดํ•œ ์˜๋ฏธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์ œ๊ธฐํ•˜๋Š” ์š”์ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์œ ๋‹ˆ์ฝ”๋“œ ๊ฐœ๋…๊ณผ ์ถฉ๋Œํ•ฉ๋‹ˆ๋‹ค. "Unicode Rune"์„ ๊ฒ€์ƒ‰ํ•  ๋•Œ ์ฃผ๋กœ Runic Unicode ๋ธ”๋ก์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ณ  Go ์–ธ์–ด ๋ฌธ์„œ์˜ ์ผ๋ถ€๋งŒ ์–ป์Šต๋‹ˆ๋‹ค.

char ๋Š” ์ ˆ๋ฐ˜ ๋‹จ์–ด์ด์ž ์ „์ฒด ๋‹จ์–ด์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ˜„์žฌ์™€ ๊ฐ™์ด ๋ฐ˜ ๊ธ€์ž ๋˜๋Š” ์ „์ฒด ๊ธ€์ž๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ์„ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด ์ฃผ๋ณ€์„ ์กฐ์‚ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์•„๋งˆ๋„ System.character ์—ฌ๊ธฐ์—์„œ ํ•ญ์ƒ ์ „์ฒด ๋ฌธ์ž๊ฐ€... :์„ ๊ธ€๋ผ์Šค:

char ๋Š” ์•ฝ๊ฐ„ ๋”์ฐํ•œ ํ‘œํ˜„์ด๋ฉฐ ASCII/๋ผํ‹ด์–ด ์ „์šฉ ์–ธ์–ด์—์„œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ์ด๋ชจํ‹ฐ์ฝ˜์˜ ๋ถ€์ƒ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹โ€‹โ€‹์นจํˆฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. char ๊ฐ€ ์ˆ˜ํ‘œ์ด๊ณ  ๋‹ค์Œ char ์œ ํ˜•์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

ํŠธ์œ„ํ„ฐ์˜ @NickCraver

utf8์€ ๊ฐ€๋ณ€ ๋„ˆ๋น„ ์ธ์ฝ”๋”ฉ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ ˆ๋ฐ˜ ๋ฌธ์ž๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ๋ฅผ ์›ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค. utf8๊ณผ utf32 ๋ชจ๋‘.

32๋น„ํŠธ ์œ ํ˜•์€ ์—ด๊ฑฐ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

์„ฑ๋Šฅ์ด๋‚˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€์ ์—์„œ indexOf, Length ๋“ฑ์ด ๋” ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

  1. ๋ฐ”์ดํŠธ ๋ฐฐ์—ด์€ ๋ถˆํˆฌ๋ช… ํ˜•์‹์— ๊ฐ€์žฅ ์ ํ•ฉํ•œ ํ‘œํ˜„์ž…๋‹ˆ๋‹ค. ์˜ˆ: ํ˜•์‹์„ ์›๋ž˜ ํ˜•์‹ ๋˜๋Š” ์ตœ์ข… ํ˜•์‹์œผ๋กœ ์œ ์ง€(ํŒŒ์ผ ์ „์†ก, ์œ ์„  ์—ฐ๊ฒฐ ๋“ฑ)
  2. ๋ฐ”์ดํŠธ ๋ฐฐ์—ด์€ ๋ฉ”๋ชจ๋ฆฌ ๋Œ€์—ญํญ๊ณผ ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ๋ฅผ ๊ฐ€์žฅ ์ž˜ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  3. ๋ฐ”์ดํŠธ ๋ฐฐ์—ด์€ ๋ฐ”์ดํŠธ ์ธก๋ฉด์—์„œ Position ๋ฐ indexOf, Length ๋“ฑ๊ณผ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ ๋ฌธ์ž์— ๋Œ€ํ•ด ๊ด€์‹ฌ์„ ๊ฐ–๊ธฐ ์‹œ์ž‘ํ•˜๋ฉด ๋Œ€๋ฌธ์ž, ๋ฌธ์ž ๋ถ„ํ• , ๋ฌธ์ž๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜๋ฉด ๋ฐ”์ดํŠธ๊ฐ€ ๊ฐ€๋ณ€ ๋„ˆ๋น„๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. Char๋Š” ๊ทธ๊ฒƒ์„ ๋” ์ข‹๊ฒŒ ๋งŒ๋“ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์ž‘์€ ๋ฌธ์ž์˜ ํฌ๊ธฐ๋ฅผ ๋‘ ๋ฐฐ๋กœ ๋Š˜๋ฆฝ๋‹ˆ๋‹ค. ๋” ๋งŽ์€ ๋ฌธ์ž๋ฅผ ํฌํ•จํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ๊ฐ€๋ณ€ ๋„ˆ๋น„์ž…๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด 32๋น„ํŠธ ๊ฐ’์€ ์‚ฌ์šฉ์ž ์ฝ”๋“œ ๊ด€์ ์—์„œ ๋งค์šฐ ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์œ„์น˜, ๊ธธ์ด ๋ฐ ๋ณด์กฐ ํ•ญ๋ชฉ(indexOf ๋“ฑ)์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ASCII ์ „์šฉ ๋ฌธ์ž์—ด๊ณผ utf8 ๋ฌธ์ž์—ด "Compact String implementation" https://github.com/dotnet/coreclr/issues/7083; ASCII ์ „์šฉ ๋ฌธ์ž์—ด์˜ ๋น ๋ฅธ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด

๊ทธ๋Ÿฌ๋‚˜ ๋‚ด๊ฐ€ ๊ฑฐ๊ธฐ์—์„œ ์ฃผ์žฅํ–ˆ๋˜ ๋ชจ๋“  ๊ฒƒ์— ๋ฐ˜๋Œ€ํ•˜๋Š” ๊ฒƒ์€... utf8์˜ 32๋น„ํŠธ ํ‘œํ˜„์ด ์–ด๋–ค ๊ฒƒ์ธ์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ์œ„์น˜๋Š” ์œ„์น˜์— ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค. ๋ฌธ์ž๋ฅผ ์ฐพ๋Š” ๊ฒƒ์€ ASCII์—์„œ์™€ ๊ฐ™์ด ๋น ๋ฅด๋ฉฐ ํ•ญ๋ชฉ์€ ๊ธฐ๋ณธ ํฌ๊ธฐ ๋“ฑ์ž…๋‹ˆ๋‹ค. ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ๋ฐ”์ดํŠธ ๋˜๋Š” ๋ฌธ์ž๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ๋ˆ„์ ๋ฉ๋‹ˆ๊นŒ?

๋กœ์˜ ๋ณ€ํ™˜์€ ๋” ๋น„์Œ‰๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋” ๋งŽ์€ ์ฒ˜๋ฆฌ ํ˜•์‹์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ €์žฅ ํ˜•์‹๋ณด๋‹ค

@migueldeicaza ๋‚ด๊ฐ€ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ชจ๋“  ํ‘œํ˜„์ด ๊ฐ’์— ํฌํ•จ๋˜๋„๋ก ๋‹จ์ผ ๋ฌธ์ž ํ˜•์‹์„ 16๋น„ํŠธ ๋ฌธ์ž์—์„œ 32๋น„ํŠธ๋กœ ํ™•์žฅํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด์„œ๋งŒ ์–ธ๊ธ‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๊ฐ’์˜ ๊ฐ€๋Šฅ์„ฑ์ด ์•„๋‹ˆ๋ผ ๋ฐ˜๋“œ์‹œ ๋‚ด๋ถ€ ํ˜•์‹์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๊ณ ๋ คํ•ด์•ผ ํ•  ์‚ฌํ•ญ(์˜ˆ: ์œ„์น˜์˜ ๊ด€๊ณ„, ๊ฒ€์ƒ‰ ๋น„์šฉ ๋“ฑ)

์ œ์ณ๋‘๊ณ : Swift๋Š” ์ „์ฒด ๋ฌธ์ž ํ˜•์‹ ๋„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

Swift๋Š” ๋ฌธ์ž์—ด์˜ ์œ ๋‹ˆ์ฝ”๋“œ ํ‘œํ˜„์— ์ ‘๊ทผํ•˜๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. for-in ๋ฌธ์œผ๋กœ ๋ฌธ์ž์—ด์„ ๋ฐ˜๋ณตํ•˜์—ฌ ์œ ๋‹ˆ์ฝ”๋“œ ํ™•์žฅ ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ๊ฐœ๋ณ„ ๋ฌธ์ž ๊ฐ’์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์„ธ์Šค๋Š” ์บ๋ฆญํ„ฐ ์ž‘์—…์— ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜๋Š” ๋‹ค๋ฅธ ์„ธ ๊ฐ€์ง€ ์œ ๋‹ˆ์ฝ”๋“œ ํ˜ธํ™˜ ํ‘œํ˜„ ์ค‘ ํ•˜๋‚˜๋กœ String ๊ฐ’์— ์•ก์„ธ์Šคํ•ฉ๋‹ˆ๋‹ค.

  • UTF-8 ์ฝ”๋“œ ๋‹จ์œ„ ๋ชจ์Œ(๋ฌธ์ž์—ด์˜ utf8 ์†์„ฑ์œผ๋กœ ์•ก์„ธ์Šค)
  • UTF-16 ์ฝ”๋“œ ๋‹จ์œ„ ๋ชจ์Œ(๋ฌธ์ž์—ด์˜ utf16 ์†์„ฑ์œผ๋กœ ์•ก์„ธ์Šค)
  • ๋ฌธ์ž์—ด์˜ UTF-32 ์ธ์ฝ”๋”ฉ ํ˜•์‹์— ํ•ด๋‹นํ•˜๋Š” 21๋น„ํŠธ ์œ ๋‹ˆ์ฝ”๋“œ ์Šค์นผ๋ผ ๊ฐ’ ๋ชจ์Œ(๋ฌธ์ž์—ด์˜ unicodeScalars ์†์„ฑ์œผ๋กœ ์•ก์„ธ์Šค)

๋‚˜๋Š” ์›๋ž˜ ๋ฌธ์ œ์—์„œ ๊ทธ๊ฒƒ์„ ๋งํ–ˆ๊ณ  ๋‹ค์‹œ ๋งํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๋ฌธ๊ตฌ๊ฐ€ ๋งˆ์Œ์— ๋“ค์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ‘œ์ค€์ด ๋งํ•˜๋Š” ๊ฒƒ์„ ํฌ๊ธฐํ•˜๋Š” ๊ฒƒ์€ ํ•ด๊ฒฐ๋˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ๊ฒƒ์ด๋ฉฐ, ์œ ๋‹ˆ์ฝ”๋“œ์— ๋ฃฌ ์ฝ”๋“œ ํŽ˜์ด์ง€๊ฐ€ ์žˆ๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ ๋” ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ๋ฟ์ž…๋‹ˆ๋‹ค.

์ด๋ฆ„์ด ์ž˜๋ชป๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

@๋ฉœ๋ฆฌ๋…ธ์—

Rune์€ ToLower[Invariant], ToUpper[Invariant], ToTitle, IsDigit, IsAlpha, IsGraphic, IsSymbol, IsControl๊ณผ ๊ฐ™์ด ์˜ค๋Š˜๋‚  Char์—์„œ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ๋Š” ๋งŽ์€ ์ž‘์—…์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • EncodeRune (๋ฃฌ์„ ๋ฐ”์ดํŠธ ๋ฒ„ํผ๋กœ ์ธ์ฝ”๋”ฉ)
  • RuneUtf8Len (๋ฃฌ์„ UTF8๋กœ ์ธ์ฝ”๋”ฉํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋ฐ”์ดํŠธ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜),
  • IsValid (์ผ๋ถ€ Int32 ๊ฐ’์ด ์œ ํšจํ•˜์ง€ ์•Š์Œ)

๊ทธ๋ฆฌ๊ณ  ๋ฌธ์ž์—ด์— ๋Œ€ํ•œ interop๊ณผ ํ•„์š”์— ๋”ฐ๋ผ Utf8string.

Go ๋ฌธ์ž์—ด ์ง€์›์„ .NET์œผ๋กœ ์ด์‹/์กฐ์ •ํ–ˆ์œผ๋ฉฐ ์ด ์„ธ์ƒ์ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ๋Š”์ง€์— ๋Œ€ํ•œ ๋ณด๊ธฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค(๋Ÿฐํƒ€์ž„ ๋„์›€๋ง ์—†์ด).

https://github.com/migueldeicaza/NStack/tree/master/NStack/unicode

@benaadams ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งํ–ˆ์Šต๋‹ˆ๋‹ค.

utf8์˜ 32๋น„ํŠธ ํ‘œํ˜„์ด ์–ด๋–ค ๊ฒƒ์ธ์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ์œ„์น˜๋Š” ์œ„์น˜์— ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค. ๋ฌธ์ž๋ฅผ ์ฐพ๋Š” ๊ฒƒ์€ ASCII์—์„œ์™€ ๊ฐ™์ด ๋น ๋ฅด๋ฉฐ ํ•ญ๋ชฉ์€ ๊ธฐ๋ณธ ํฌ๊ธฐ ๋“ฑ์ž…๋‹ˆ๋‹ค. ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ๋ฐ”์ดํŠธ ๋˜๋Š” ๋ฌธ์ž๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ๋ˆ„์ ๋ฉ๋‹ˆ๊นŒ?

UTF8์€ ๋ฉ”๋ชจ๋ฆฌ ๋‚ด ํ‘œํ˜„์œผ๋กœ ๊ณ„์† ์กด์žฌํ•˜๊ณ  ๊ณ„์† ํ‘œํ˜„์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ธฐ์กด UTF16 ๋ฌธ์ž์—ด(System.String) ๋˜๋Š” ๋‹ค๊ฐ€์˜ค๋Š” UTF8 ๋ฌธ์ž์—ด(Utf8String)์„ Chars(๋‹น์‹ ๊ณผ ๋‚ด๊ฐ€ ๋ชจ๋‘ ๋™์˜ํ•˜๋Š” ์ด์œ )๊ฐ€ ์•„๋‹ˆ๋ผ Runes๋กœ ๋””์ฝ”๋”ฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ช‡ ๊ฐ€์ง€ ์˜ˆ๋Š” Utf8 ๋ฌธ์ž์—ด์„ ๋ฃฌ ๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

https://github.com/migueldeicaza/NStack/blob/6a071ca5c026ca71c10ead4f7232e2fa0673baf9/NStack/strings/ustring.cs#L756

utf8 ๋ฌธ์ž์—ด์— ๋ฃฌ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๊นŒ?

https://github.com/migueldeicaza/NStack/blob/6a071ca5c026ca71c10ead4f7232e2fa0673baf9/NStack/strings/ustring.cs#L855

๋ฐฉ๊ธˆ ์ธ๋ฑ์„œ๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•˜์Œ์„ ์•Œ์•„์ฐจ๋ ธ์Šต๋‹ˆ๋‹ค("n๋ฒˆ์งธ ๋ฃฌ ๊ฐ€์ ธ์˜ค๊ธฐ").

๋ฌธ์ž์—ด์—์„œ N๋ฒˆ์งธ ๋ฃฌ์— ๋Œ€ํ•œ ์•ก์„ธ์Šค ์†๋„๋Š” ๋ฃฌ ์ž์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ์ €์žฅ์†Œ์˜ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ €์žฅ์†Œ๊ฐ€ UTF32์ธ ๊ฒฝ์šฐ ๋ชจ๋“  ๋ฃฌ์— ์ง์ ‘ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ฌด๋„ ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์€ ํ•™๋ฌธ์ ์ž…๋‹ˆ๋‹ค. UTF16 ๋ฐ UTF8์˜ N๋ฒˆ์งธ ์š”์†Œ์— ์•ก์„ธ์Šคํ•˜๋ ค๋ฉด ๋ฌธ์ž์—ด์„ ๊ตฌ์„ฑํ•˜๋Š” ์š”์†Œ(๋ฐ”์ดํŠธ ๋˜๋Š” 16๋น„ํŠธ ์ •์ˆ˜)๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์Šค์บ”ํ•˜์—ฌ ์˜ฌ๋ฐ”๋ฅธ ๊ฒฝ๊ณ„๋ฅผ ๊ฒฐ์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•์„ฑ์— ๊ด€๊ณ„์—†์ด n๋ฒˆ์งธ ๋ฌธ์ž๋งŒ ๋ฐ˜ํ™˜ํ•˜๋Š” String[int n] { get; } ์™€ ํ˜ผ๋™ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

@benaadams ์Šค์œ„ํ”„ํŠธ ์บ๋ฆญํ„ฐ๋Š” ๋ฃฌ๋ณด๋‹ค ํ•œ ๋‹จ๊ณ„ ๋†’์€ ๋ ˆ๋ฒจ์ž…๋‹ˆ๋‹ค. swift์˜ ๋ฌธ์ž๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ ๋ฃฌ์œผ๋กœ ๊ตฌ์„ฑ๋œ "ํ™•์žฅ๋œ ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ"์ด๋ฉฐ, ๊ฒฐํ•ฉ๋  ๋•Œ ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ž๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ Swift ์บ๋ฆญํ„ฐ๋Š” ๊ณ ์ •๋œ 32๋น„ํŠธ ํฌ๊ธฐ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ฐ€๋ณ€ ๊ธธ์ด์ž…๋‹ˆ๋‹ค(๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋„ ๊ทธ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ ธ์•ผ ํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ์œ ํ˜•์— ์†ํ•ฉ๋‹ˆ๋‹ค). ๋‹ค์Œ์€ ํ•ด๋‹น ํŽ˜์ด์ง€์˜ ์˜ˆ์ด์ง€๋งŒ ์ด๋ชจํ‹ฐ์ฝ˜์˜ ์ƒ‰์กฐ ์„ค์ •๊นŒ์ง€ ํ™•์žฅ๋ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ ์˜ˆ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ž รฉ๋Š” ๋‹จ์ผ ์œ ๋‹ˆ์ฝ”๋“œ ์Šค์นผ๋ผ รฉ(LATIN SMALL LETTER E WITH ACUTE ๋˜๋Š” U+00E9)๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋™์ผํ•œ ๋ฌธ์ž๋Š” ํ‘œ์ค€ ๋ฌธ์ž e(LATIN SMALL LETTER E ๋˜๋Š” U+0065) ๋‹ค์Œ์— COMBINING ACUTE ACCENT ์Šค์นผ๋ผ(U+0301)๊ฐ€ ์˜ค๋Š” ํ•œ ์Œ์˜ ์Šค์นผ๋ผ๋กœ๋„ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. COMBINING ACUTE ACCENT ์Šค์นผ๋ผ๋Š” ๊ทธ ์•ž์— ์˜ค๋Š” ์Šค์นผ๋ผ์— ๊ทธ๋ž˜ํ”ฝ์œผ๋กœ ์ ์šฉ๋˜์–ด ์œ ๋‹ˆ์ฝ”๋“œ ์ธ์‹ ํ…์ŠคํŠธ ๋ Œ๋”๋ง ์‹œ์Šคํ…œ์—์„œ ๋ Œ๋”๋ง๋  ๋•Œ e๋ฅผ รฉ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

์ €์—๊ฒŒ grapheme ๋‹จ์–ด๋Š” ๋” ์ž๊ธฐ ์„ค๋ช…์ ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๋ฆ„์— ๋‘ ์„ผํŠธ, ๊ฐ•์กฐํ•˜์—ฌ ๋ฌธ์ž์—ด์— ๋Œ€ํ•œ Go ๊ฒŒ์‹œ๋ฌผ์„ ๋‹ค์‹œ ์ธ์šฉํ•ฉ๋‹ˆ๋‹ค.

" Code point "๋Š” ์ž…์ด ๋–ก๋ฒŒ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— Go์—์„œ๋Š” ๊ฐœ๋…์— ๋Œ€ํ•ด ๋” ์งง์€ ์šฉ์–ด์ธ ๋ฃฌ์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ์ด ์šฉ์–ด๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ์†Œ์Šค ์ฝ”๋“œ์— ๋‚˜ํƒ€๋‚˜๋ฉฐ "์ฝ”๋“œ ํฌ์ธํŠธ"์™€ ์ •ํ™•ํžˆ ๊ฐ™์€ ์˜๋ฏธ ์ด๋ฉฐ ํฅ๋ฏธ๋กœ์šด ์ถ”๊ฐ€ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” @blowdart ์— 100% ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฃฌ์ด๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฒƒ์€ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ณ  ์ž˜๋ชป๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์œ ๋‹ˆ์ฝ”๋“œ ํ‘œ์ค€ ์€ ๋„์ž… ์žฅ์˜ ์ฒซ ํŽ˜์ด์ง€ ์—๋งŒ ์ฝ”๋“œ ํฌ์ธํŠธ๋ฅผ ์„ธ ๋ฒˆ ์–ธ๊ธ‰ํ•˜์ง€๋งŒ ๋ฃฌ ์ด๋ผ๋Š” ์šฉ์–ด๋Š” ์–ด๋””์—๋„ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์ด ์ฝ”๋“œ ํฌ์ธํŠธ๋ผ๋ฉด ๊ทธ ์ด๋ฆ„์€ code point ๋กœ ๊ฐ„๋‹จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฃฌ ์ด๋ผ๋Š” ์šฉ์–ด๊ฐ€ ๊ทœ๊ฒฉ์— ๋‚˜์˜ค์ง€ ์•Š์•˜๋‹ค๋ฉด ๊ดœ์ฐฎ์„ ํ…๋ฐ , ๋ฌธ์ œ๋Š” ๋ฃฌ๊ณผ ๊ด€๋ จํ•˜์—ฌ 8์žฅ์—์„œ ์—ฌ๋Ÿฌ ๋ฒˆ ๋“ฑ์žฅํ•œ๋‹ค๋Š” ์ ์ด๋‹ค. ๋‹จ์ˆœํžˆ ์ž˜๋ชป๋œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ฌธ์ œ๋ฅผ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๊ณผ ์ ๊ทน์ ์œผ๋กœ ํ˜ผ๋™ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ €์—๊ฒŒ grapheme ๋‹จ์–ด๋Š” ๋” ์ž๊ธฐ ์„ค๋ช…์ ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ์•ฝ 32๋น„ํŠธ ์ฝ”๋“œ ํฌ์ธํŠธ๋ผ๋ฉด grapheme ๋ผ๋Š” ์šฉ์–ด๋Š” ์ž์†Œ๊ฐ€ ๋˜ ๋‹ค๋ฅธ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ข…์ข… ์ฝ”๋“œ ํฌ์ธํŠธ ๋ฐ์ดํ„ฐ ์œ ํ˜•์„ ์›ํ–ˆ์Šต๋‹ˆ๋‹ค . ์ž˜ ํ…Œ์ŠคํŠธ ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ํ•  ์ˆ˜ ์žˆ์Œ). ์ด๊ฒƒ์„ CodePoint ์™€ ๊ฐ™์ด ๋ถ€๋ฅด์ง€ ๋ง์•„์•ผ ํ•˜๋Š” ์ด์œ ๋ฅผ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌํ•œ ์œ ํ˜•์ด ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ซ๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์€ ์–ด์จŒ๋“  ๋ฃฌ์˜ ๊ด€์ ์ด ์•„๋‹ˆ๋ผ ์ฝ”๋“œ ํฌ์ธํŠธ ๊ด€์ ์—์„œ ์ƒ๊ฐํ•˜๊ณ  ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜๋Š” ์ฝ”๋“œ ํฌ์ธํŠธ ์™€ ๋ฃฌ์„ ์ž‘์—…์˜ ๋ณ„๋„ ๋ถ€๋ถ„์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. แšฑแšขแšพแšช แ›’แ›‡แšฆ แ›ฅแ›แ›šแ›– แ›’แšฑแšฃแšณแ›–แšข/rรบna bรฉoรพ stille bryceu/runes๋Š” ์—ฌ์ „ํžˆ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” 1๋…„์— ํ•œ ๋ฒˆ ์ •๋„ ๋ฃฌ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๊ณ , ์ผ๋ฐ˜์ ์œผ๋กœ ๋””์ง€ํ„ธ๋ณด๋‹ค๋Š” ์–‘ํ”ผ์ง€์™€ ์ž‰ํฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ๋””์ง€ํ„ธ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ์‚ฌ๋žŒ๋“ค๋„ ๋ถ„๋ช…ํžˆ ์žˆ์Šต๋‹ˆ๋‹ค. (์‹ฌ์ง€์–ด 20์„ธ๊ธฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ ๋„ WWII ์‹œ๋Œ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๊ด€ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ ์‚ฌ๋ก€๋ฅผ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.)

์ข…์ข… ์˜ฅํ…Ÿ โ†’ ๋ฌธ์ž(์ด๋ฏธ .NET์—์„œ ์ž˜ ์ฒ˜๋ฆฌ๋จ), ๋ฌธ์ž โ†’ ์ฝ”๋“œ ํฌ์ธํŠธ, ์ฝ”๋“œ ํฌ์ธํŠธ โ†’ ์ž์†Œ๋กœ ์ด๋™ํ•˜๊ธฐ๋ฅผ ์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Grapheme ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹๋” ๊นŒ๋‹ค๋กญ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ๋กœ์„œ๋Š” ์ด๊ฒƒ์„ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ๋‹จ๊ณ„ : ์šฐ๋ฆฌ๊ฐ€ ์ฐพ๊ณ  ์žˆ๋Š” ๊ฒƒ์€ ์œ„์˜ ํ”ผ๋“œ๋ฐฑ์„ ํฌํ•จํ•  ๊ณต์‹์ ์ธ ์ œ์•ˆ์ž…๋‹ˆ๋‹ค(์œ ํ˜•์˜ ์‹ค์ œ ์ด๋ฆ„ ๋ฐ Int32๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋Œ€์กฐ์ ์œผ๋กœ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์ ).

์ œ์•ˆ๋œ API์™€ ์ดˆ๊ธฐ ๊ตฌํ˜„ ๋ชจ๋‘์—์„œ ๋ฌธ์ œ๋ฅผ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.

https://github.com/migueldeicaza/NStack/blob/master/NStack/unicode/Rune.cs

์œ ํ˜• ์ด๋ฆ„ ์ง€์ •๊ณผ ๊ด€๋ จํ•˜์—ฌ ์œ ํ˜•์— ๋Œ€ํ•œ ์œ ํšจํ•œ ์ž‘์—…์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ์œ„์น˜์™€ ์œ ํ˜•๋ณ„ ๊ธฐ๋Šฅ(์ผ๋ถ€ ์˜ˆ์ œ๋Š” ๊ตฌํ˜„ ์ฐธ์กฐ)์„ ๊ฐ–๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

@migueldeicaza ๋ฅผ ๊ฒ€ํ† ํ•  ์ค€๋น„๊ฐ€ ๋œ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œํ•˜๊ธฐ ์ „์— ์œ ํ˜•์˜ ์‹ค์ œ ์ด๋ฆ„ ์ง€์ •์— ๋Œ€ํ•œ ์šฐ๋ ค์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ? ์œ ํ˜•์„ ์„ค๋ช…ํ•˜๋Š” ๋ฐ CodePoint๊ฐ€ ๋” ๋‚˜์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ?

์ฝ”๋“œํฌ์ธํŠธ๋ฅผ ์ด๋ฆ„์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ์ฃผ์žฅ์ด ์•ฝํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋”์ฐํ•œ ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค. ์žฅ๊ธฐ์ ์œผ๋กœ ์ด๊ฒƒ์€ ๊ธฐ์กด ์ฝ”๋“œ์—์„œ "char"์˜ ๋ชจ๋“  ๋‹จ์ผ ์‚ฌ์šฉ์„ ๋Œ€์ฒดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ ์ ์ ˆํ•œ ์œ ๋‹ˆ์ฝ”๋“œ ์ง€์›์„ ๋ฐ›๊ธฐ๋ฅผ ๋ฐ”๋ž€๋‹ค๋ฉด ๋ง์ž…๋‹ˆ๋‹ค.

Rust์ฒ˜๋Ÿผ "char"๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ์œผ๋ฉด ์ข‹๊ฒ ์ง€๋งŒ ์Šฌํ”„๊ฒŒ๋„ ์ด๋ฏธ ์‚ฌ์šฉํ–ˆ๊ณ  ๊นจ์ง„ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Go๊ฐ€ ์ด ์ด๋ฆ„์„ ๋ฐ›์•„๋“ค์ธ ๊ฒƒ์€ ์ข‹์€ ์„ ๋ก€์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” code point ๊ฐ€ ์—ฌ๊ธฐ์— ์‚ฌ์šฉํ•˜๊ธฐ์— ์˜ฌ๋ฐ”๋ฅธ ์šฉ์–ด๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์ตœ์†Œํ•œ ์œ ๋‹ˆ์ฝ”๋“œ ํ‘œ์ค€์— ๋”ฐ๋ผ 10FFFF(http://unicode.org/glossary/#code_point) ์ด์ƒ์˜ ๊ฐ’์€ ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” rune ๋ผ๋Š” ์šฉ์–ด๋ฅผ ์ข‹์•„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์œ ๋‹ˆ์ฝ”๋“œ์™€ ๋‹ค๋ฅธ ๊ณณ์—์„œ ์ „๋ฐ˜์ ์œผ๋กœ ํ˜ผ๋ž€์„ ์•ผ๊ธฐํ•  ๊ธฐ์กด ์‚ฌ์šฉ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ธฐ์กด ์‚ฌ์šฉ์ž ์œ ํ˜•๊ณผ ์ถฉ๋Œํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๊ฝค ๋†’๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค(ํŠนํžˆ 'Rune'์ด ํŠน์ • ๊ฒŒ์ž„ ๊ฐœ์ฒด๋ฅผ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋Š” Unity์™€ ๊ฐ™์€ ๊ฒฝ์šฐ).

๊ทธ๋Ÿฌ๋‚˜ C++ 11 char32_t ์œ ํ˜•์„ ํฌํ•จํ•˜๋Š” ์œ ํ˜•์ด๋ผ๋Š” ์•„์ด๋””์–ด๊ฐ€ ๋งˆ์Œ์— ๋“ญ๋‹ˆ๋‹ค. ์ด๋ฆ„๋งŒ ๋‹ค๋ฅผ ๋ฟ์ž…๋‹ˆ๋‹ค.

Char32 ์— ๋Œ€ํ•ด ํ•  ๋ง์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์š”์ ์€ ์ •์ˆ˜ ํ˜•์‹์˜ ํ˜•์‹ ์ด๋ฆ„๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ ํฌ์ธํŠธ ์ˆ˜์ค€์ด ์•„๋‹Œ ์บ๋ฆญํ„ฐ ๊ฐœ๋… ์ˆ˜์ค€์—์„œ ์ด์•ผ๊ธฐํ•ฉ๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ ์ด๋ฆ„์ด ์•„๋‹™๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” nint ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— nchar ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์„ ๋ก€๋Š” nchar ๋ฐ nvarchar ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ nchar ๋Š” ๊ตญ๊ฐ€ ๋ฌธ์ž/๊ตญ๊ฐ€ ๋ฌธ์ž์ด๊ณ  nvarchar ๋Š” ๊ตญ๊ฐ€ ๋ฌธ์ž ๊ฐ€๋ณ€/๊ตญ๊ฐ€ ๋ฌธ์ž ๊ฐ€๋ณ€์ž…๋‹ˆ๋‹ค. ์œ ๋‹ˆ์ฝ”๋“œ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ํ•„๋“œ ์œ ํ˜•์€ ๋ฌด์—‡์ด๋ฉฐ ์ผ๋ถ€ ISO ํ‘œ์ค€๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋Š ๊ฒƒ์ด SQL์ธ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

๋ฃฌ์˜ ์ด ์œ ๋‹ˆ์ฝ”๋“œ ์‚ฌ์šฉ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๊ทธ๊ฒƒ์€ ๋‚˜์—๊ฒŒ ์ƒˆ๋กœ์šด ์†Œ์‹์ด๋‹ค.

U+16A0 ~ U+16F8

์œ ๋‹ˆ์ฝ”๋“œ ํ‘œ์ค€์˜ ํŠน์ • ์ฝ”๋“œ ํŽ˜์ด์ง€๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด ์Šค๋ ˆ๋“œ์—์„œ ๋ช‡ ๋ฒˆ ์–ธ๊ธ‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. http://unicode.org/charts/PDF/U16A0.pdf

์•„ ๋ฃฌ์ด ์•„๋‹ˆ๋ผ ๋ฃฌ์ž…๋‹ˆ๋‹ค.

๋ฐฑ์—… ์ด๋ฆ„(System.Rune ๋˜๋Š” System.Char32)์€ C#์— ํˆฌ์˜๋  ๋ ˆ์ด๋ธ”๋งŒํผ ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ฒซ์งธ: ์˜ˆ, ์˜ˆ, ๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์— ๋Œ€ํ•ด ๋” ๋งŽ์ด ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด ์•„์ด๋””์–ด๋ฅผ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์‹ค ์šฐ๋ฆฌ๋Š” ์ž ์‹œ ๋™์•ˆ Visual Studio์˜ Git ํ˜ธํ™˜์„ฑ์—์„œ ์‚ฌ์šฉ์ž ์ง€์ • ๋ฌธ์ž์—ด ํด๋ž˜์Šค์™€ ๋ฌธ์ž ๊ตฌ์กฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค(Git์€ Utf-8๋กœ ๋งํ•˜๊ณ  ๋ชจ๋“  ๊ฒƒ์„ ํŠธ๋žœ์Šค์ฝ”๋”ฉํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ๋Š๋ฆฝ๋‹ˆ๋‹ค).

์ •์  ๋ฉ”์„œ๋“œ ์ด๋ฆ„์— ๋Œ€ํ•ด ์ž„์˜์˜ ์งง์€ ์ด๋ฆ„ ์ง€์ •์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? Char.IsPunctuation ๊ฐ€ ํ˜„์žฌ ๋ฐฉ๋ฒ•์ธ ๊ฒฝ์šฐ Rune.IsPunctuation ๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ๊ฒƒ์œผ๋กœ ๋ฏธ๋Ÿฌ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด๊ฒƒ์ด ๋ฐ›์•„๋“ค์—ฌ์ง„๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด(ํ•ญ์ƒ ์œ„ํ—˜ํ•ฉ๋‹ˆ๋‹ค), ๋ณธ์งˆ์ ์ธ rune ๋˜๋Š” c32 ๋˜๋Š” char ๋ฅผ System.Rune ๊ตฌํ˜„์œผ๋กœ ์™„์ „ํžˆ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

uchar unichar ๋˜๋Š” uchar $๋ฅผ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ์–ด๋Š ์ชฝ์„ ์„ ํƒํ•˜๋“ ์ง€ ์–ธ์–ด๋ณ„ ๋ณ„์นญ์„ ์–ป์„ ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ €๋Š” ๊ฐœ์ธ์ ์œผ๋กœ ๊ธฐ๋ณธ ์œ ํ˜•์— ์–ธ์–ด ๋ณ„์นญ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋งค์šฐ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ @whoisj ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค - ์งง์€/์•ฝ์–ด๋ณด๋‹ค ์ „์ฒด ๋ฉ”์„œ๋“œ ์ด๋ฆ„์„ ํ™•์‹คํžˆ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ @whoisj ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค - ์งง์€/์•ฝ์–ด๋ณด๋‹ค ์ „์ฒด ๋ฉ”์„œ๋“œ ์ด๋ฆ„์„ ํ™•์‹คํžˆ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

IMO ์–ธ์–ด(๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)๋Š” ์ „์ฒด, ์ถ•์•ฝ๋œ ์ด๋ฆ„์„ ์„ ํƒํ•˜๊ฑฐ๋‚˜ ์•ฝ์–ด(์˜ˆ: strcmp, memcpy ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋Š” C)๋ฅผ ์„ ํƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์•„๋‹ˆ๋ฉด char ๋ฅผ System.Rune ๊ตฌํ˜„์œผ๋กœ ์™„์ „ํžˆ ๋ฐ”๊พธ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

๊ทธ๊ฒƒ์€ ์ƒ๋‹นํžˆ ๋ช…๋ฐฑํ•œ ์ด์œ ๋กœ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ์ƒ๋‹นํžˆ ๋ช…๋ฐฑํ•œ ์ด์œ ๋กœ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚ด ์˜๊ฒฌ์€ ๋Œ€๋ถ€๋ถ„ ํ˜€์™€ ๋ณผ์ด์—ˆ๊ณ  ํฌ๋ง์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. 16๋น„ํŠธ ๋ฌธ์ž ์œ ํ˜•์€ ์ฒ˜์Œ๋ถ€ํ„ฐ ์‹ค์ˆ˜์˜€์Šต๋‹ˆ๋‹ค.

์ด๋ฆ„ ์ง€์ •์„ ์ž˜ํ•˜๋ฉด ์ˆ˜์ •๋ฉ๋‹ˆ๋‹ค.

์ œ๊ณต๋œ API์— ๋‹ค๋ฅธ ์ž‘์€ ๋ถˆ์ผ์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@migueldeicaza

์•„ ๋ฃฌ์ด ์•„๋‹ˆ๋ผ ๋ฃฌ์ž…๋‹ˆ๋‹ค.

๋ฃฌ ๋ฌธ์ž ๋Š” ํ˜•์šฉ์‚ฌ, ๋ฃฌ ๋ช…์‚ฌ์ž…๋‹ˆ๋‹ค. ๋ฃฌ ๋ฌธ์ž๋Š” ๋ชจ๋‘ ๋ฃฌ ๋ฌธ์ž์ž…๋‹ˆ๋‹ค.

_Runic_์€ ํ˜•์šฉ์‚ฌ, _rune_๋Š” ๋ช…์‚ฌ์ž…๋‹ˆ๋‹ค. ๋ฃฌ ๋ฌธ์ž๋Š” ๋ชจ๋‘ ๋ฃฌ ๋ฌธ์ž์ž…๋‹ˆ๋‹ค.

"Cortana: define _'rune'_"์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๊ณต์ •ํ•ฉ๋‹ˆ๋‹ค.

๋กœ๋งˆ ์•ŒํŒŒ๋ฒณ๊ณผ ๊ด€๋ จ๋œ ๊ณ ๋Œ€ ๊ฒŒ๋ฅด๋งŒ ์•ŒํŒŒ๋ฒณ์˜ ๋ฌธ์ž.

์•„ ์˜ˆ, "๋ฃฌ"์ด๋ผ๋Š” ๋‹จ์–ด๋ฅผ ๋ณผ ๋•Œ๋งˆ๋‹ค "The Runic Unicode Block"์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๋Š” ์•„๋ฌด๋„ ์ฝ์ง€ ์•Š์€ ์‚ฌ์–‘์˜ ์ด ๋ชจํ˜ธํ•œ ์žฅ์ด ์ฆ‰์‹œ ์ƒ๊ฐ๋‚ฉ๋‹ˆ๋‹ค.

๐Ÿ˜† ์–ด๋ฆด ์  ํ†จํ‚จ์„ ์ฝ์—ˆ๋˜ ๊ธฐ์–ต์ด ๋– ์˜ค๋ฅธ๋‹ค.

แ›แ›ซแšฆแ›แ›œแšฒแ›ซแ›Ÿแš แ›ซแšฑแšขแšพแ›–แ›‹

๋„ค, ๊ตฌ์ฒด์ ์œผ๋กœ ์‚ฌ์–‘์€ ์ƒ๊ฐํ•˜์ง€ ์•Š์ง€๋งŒ ์‚ฌ์–‘์ด ์ฐธ์กฐํ•˜๋Š” ๋ฌธ์ž ์œ ํ˜•์€ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

rune ๋ผ๊ณ  ํ•˜๋ฉด ๋งˆ๋ฒ•, ํŒํƒ€์ง€, ์ˆ˜์ˆ˜๊ป˜๋ผ ๊ฐ™์€ ํผ์ฆ, ๊ณ ๋Œ€ ์–ธ์–ด ๋“ฑ์„ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

"๋ฃฌ"์ด๋ผ๋Š” ๋‹จ์–ด๊ฐ€ ๋ณด์ด์ง€ ์•Š๊ณ  ์ฆ‰์‹œ "์•„ ์ด๊ฒƒ์€ ๋ถ„๋ช…ํžˆ 16A0..16F8 ๋ฒ”์œ„์˜ ๊ณ ์œ ํ•œ ๊ฐ’์œผ๋กœ ๊ฐ’์ด ์ œํ•œ๋˜๋Š” ์œ ๋‹ˆ์ฝ”๋“œ 7.0 ๋ฃฌ ๋ธ”๋ก์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค"๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—์„œ Tanner๊ฐ€ ํ•œ ๋ชฉ์†Œ๋ฆฌ๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๊ณ  ์—ฌ๋Ÿฌ๋ถ„ ์ค‘ ์ผ๋ถ€๋Š” ์—ฌ์ „ํžˆ "ํ•˜์ง€๋งŒ Miguel, ๋‚˜๋Š” 'rune'์ด๋ผ๋Š” ๋‹จ์–ด๋ฅผ ๋ณด๊ณ  ์ฆ‰์‹œ 88๊ฐœ์˜ ๊ฐ€๋Šฅํ•œ ๊ฐ’๋งŒ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ ์œ ํ˜•์ด ๋– ์˜ฌ๋ž์Šต๋‹ˆ๋‹ค"๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์••๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋‹น์‹ ์ด ๊ณ ๊ตฐ๋ถ„ํˆฌํ•˜๋Š” ๋ฌธ์ œ๋ผ๋ฉด, ๋‚ด ํ˜•์ œ/์ž๋งค, ๋‹น์‹ ์„ ์œ„ํ•œ ์†Œ์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๋” ํฐ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ํŠ€๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ํ•œ ๋‹ฌ์ด ์กฐ๊ธˆ ๋„˜๋Š” ๊ธฐ๊ฐ„ ๋™์•ˆ ํฅ๋ถ„๊ณผ ๋ง์„ค์ž„์ด ๋’ค์„ž์—ฌ ์ž ์‹œ ๋™์•ˆ ์ด ์Šค๋ ˆ๋“œ๋ฅผ ๋”ฐ๋ผ์™”์Šต๋‹ˆ๋‹ค. ์ง€๋‚œ ๋‹ฌ์— ๊ตญ์ œํ™” ๋ฐ ์œ ๋‹ˆ์ฝ”๋“œ ํšŒ์˜์— ์ฐธ์„ํ–ˆ๋Š”๋ฐ .NET์„ ๋‹ค๋ฃฌ ํ”„๋ ˆ์  ํ…Œ์ด์…˜์€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. .NET Framework์— ์ธ์‹ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ธ๊ณ„ํ™” ๊ธฐ๋Šฅ์˜ ์—ญ์‚ฌ๋ฅผ ๊ณ ๋ คํ•  ๋•Œ ๋ฐ˜๋“œ์‹œ ๋ฒŒ์ง€ ์•Š์€ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธด ํ•˜์ง€๋งŒ ์ €๋Š” C# ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ข‹์•„ํ•˜๊ณ  ์ง„์ •ํ•œ ๊ธ€๋กœ๋ฒŒ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ .NET์˜ ์œ„์น˜๋ฅผ โ€‹โ€‹๊ฐ•ํ™”ํ•˜๋Š” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ ˆ๋Œ€์ ์œผ๋กœ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์ด ์ œ์•ˆ์ด ๊ตญ์ œํ™” ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ์†Œํ”„ํŠธ์›จ์–ด์— ๋Œ€ํ•ด ๊ธฐ๋Œ€ํ•˜๋Š” ํ‘œ์ค€์„ ์ˆ˜์šฉํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€๋Š” ์ข‹์€ ๋‹จ๊ณ„๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚ด ์ฃผ์ €๋Š” ๋Œ€๋ถ€๋ถ„ ์œ ํ˜• ์ด๋ฆ„์— ๋Œ€ํ•ด ๋ง๋‹คํˆผ์„ ํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. Go์˜ ์„ค๊ณ„์ž๋“ค์ด "rune"์ด๋ผ๋Š” ์ด๋ฆ„์„ ์„ ํƒํ•œ ๊ฒƒ์€ ์‚ฌ์‹ค์ด์ง€๋งŒ ์œ„์— ๋ฐ˜๋ณต์ ์œผ๋กœ ๋‚˜์—ด๋œ ์ด์œ ๋กœ ๋ฌธ์ œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ œ๋Œ€๋กœ ๋ฃฌ์ด๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ์ฝ”๋“œ ํฌ์ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์กด๊ฒฝ๋ฐ›๋Š” ํ‘œ์ค€์— ๊ฐ€๊น๊ฒŒ ๊นŽ๊ณ  ์‚ฌ์–‘์˜ ์ผ๋ถ€์ธ ์šฉ์–ด๋ฅผ ์žฌ์ •์˜ํ•˜๋ ค๋Š” ์ œ์•ˆ์— ๋™์˜ํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€, ๋Œ€๋ถ€๋ถ„์˜ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ด ์šฉ์–ด๋ฅผ ๋ชจ๋ฅธ๋‹ค๋Š” ์ฃผ์žฅ์€ ์ด ์œ ํ˜•์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ๊ฐ€์žฅ ๊ด€์‹ฌ์ด ์žˆ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์œ ๋‹ˆ์ฝ”๋“œ ์‚ฌ์–‘์„ ์ดํ•ดํ•˜๊ณ  "๋ฃฌ"์ด ์‹ค์ œ๋กœ ๋ฌด์—‡์ธ์ง€ ์ž˜ ์•Œ๊ณ  ์žˆ๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ ๊ฑฐ์ง“์ž…๋‹ˆ๋‹ค. ์šฉ์–ด๋ฅผ ํ˜ผํ•ฉํ•˜๋ฉด ์กด์žฌํ•  ์ˆ˜ ์žˆ๋Š” ์ด์ƒํ•จ์„ ์ƒ์ƒํ•ด ๋ณด์‹ญ์‹œ์˜ค.

Rune.IsRune(new Rune('แ›')); // evaluates to true
Rune.IsRune(new Rune('I')); // evaluates to false

๋ฌผ๋ก , ๋‚˜๋Š” ์ƒˆ๋กœ์šด ์ด๋ฆ„์„ ์ œ๊ณตํ•˜์ง€ ์•Š๊ณ  ๋น„ํŒํ•˜๋Š” ์‰ฌ์šด ๊ธธ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. CodePoint ์˜ ์ด์ „ ์ œ์•ˆ์ด ๊ฐ€์žฅ ์ž๋ช…ํ•œ ์˜ต์…˜์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ(์›๋ž˜ ๋ฌธ์ œ ์„ค๋ช…์— ๋‚˜ํƒ€๋‚จ) char32 ๋Š” ๊ธฐ์กด ๊ธฐ๋ณธ ์œ ํ˜•๊ณผ ๋” ๋งŽ์€ ํŒจ๋ฆฌํ‹ฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ๋ชจ๋“  ์ฝ”๋“œ ํฌ์ธํŠธ๊ฐ€ ๋ฌธ์ž๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์„ ์ฃผ์ €ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.) ๋ชฉํ‘œ๊ฐ€ .NET์— ๋” ๋‚˜์€ ์œ ๋‹ˆ์ฝ”๋“œ ์ง€์›์„ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์ด๋ผ๋ฉด ์ €๋Š” ๊ทธ ๊ฒฝ๋กœ๋ฅผ ์ ˆ๋Œ€์ ์œผ๋กœ ์ง€์ง€ํ•˜์ง€๋งŒ ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์‚ฌ์–‘์„ ๋”ฐ๋ฅด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์„ธ ๊ฐ€์ง€ ์ œ์•ˆ:

  1. Rune ํด๋ž˜์Šค์— ์ค‘์š”ํ•œ "IsCombining"์ด ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ ์—†์ด๋Š” ์ผ๋ จ์˜ ๋ฃฌ(์ฝ”๋“œ ํฌ์ธํŠธ)์„ ์ผ๋ จ์˜ ์ž์†Œ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  1. ํ•ด๋‹น Graphme ํด๋ž˜์Šค๋„ ๊ฐ–๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด ์ปจํ…์ŠคํŠธ์—์„œ ์ž์†Œ๋Š” ์‹ค์ œ๋กœ ์ฒซ ๋ฒˆ์งธ ๋ฃฌ์ด ๊ฒฐํ•ฉ๋˜์ง€ ์•Š๊ณ  ๋‚˜๋จธ์ง€ ๋ฃฌ์ด ๊ฒฐํ•ฉ๋˜๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ ๋ฃฌ(์ฝ”๋“œ ํฌ์ธํŠธ) ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ "๋ณด์ด๋Š” ๋ฌธ์ž" ๋ฉ์–ด๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด + GRAVE๋Š” ํ•˜๋‚˜์˜ ์ž์†Œ๋ฅผ ํ˜•์„ฑํ•˜๋Š” ๋‘ ๊ฐœ์˜ ๋ฃฌ์ž…๋‹ˆ๋‹ค.

  2. ๋„คํŠธ์›Œํ‚น์—์„œ ์šฐ๋ฆฌ๋Š” ์ข…์ข… ๋ฐ”์ดํŠธ๊ฐ€ ์™„์ „ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด์™€ ๊ฐ™์€ "๋ฌธ์ž์—ด"๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•˜๋Š” ๋ฐ”์ดํŠธ ๋ฉ์–ด๋ฆฌ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค(์˜ˆ: ์ผ๋ถ€ ๋ฐ”์ดํŠธ์— ๋Œ€ํ•ด ๋“ค์—ˆ์ง€๋งŒ ๋‹ค์ค‘ ๋ฐ”์ดํŠธ ์‹œํ€€์Šค์˜ ๋งˆ์ง€๋ง‰ ๋ฐ”์ดํŠธ๋Š” ' t ๊ฝค ๋„์ฐฉํ–ˆ์Šต๋‹ˆ๋‹ค). ๋‹ค์ค‘ ๋ฐ”์ดํŠธ ์‹œํ€€์Šค์˜ ๋งˆ์ง€๋ง‰ ๋ฐ”์ดํŠธ๊ฐ€ ๋ˆ„๋ฝ๋œ ๊ฒƒ์ด ๋‹ค์Œ ๋ฐ”์ดํŠธ ์„ธํŠธ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์ˆ˜์ •๋  ์ •์ƒ์ ์ธ ์ƒํ™ฉ์œผ๋กœ ๊ฐ„์ฃผ๋˜๋„๋ก ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์„ ๋ฃฌ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ™•์‹คํ•œ ๋ฐฉ๋ฒ•์€ ๋ณด์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์œ ๋‹ˆ์ฝ”๋“œ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๊ณ  ์ด๊ฒƒ์„ CodePoint๋ผ๊ณ  ๋ถ€๋ฅด์‹ญ์‹œ์˜ค. ์˜ˆ, ์œ ๋‹ˆ์ฝ”๋“œ ์ปจ์†Œ์‹œ์—„์€ ์ฐจ์ด์ ์„ ์„ค๋ช…ํ•˜๋Š” ๋ฐ ๋”์ฐํ•œ ์ผ์„ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•ด๊ฒฐ์ฑ…์€ ๋ช…ํ™•ํ•˜๊ณ  ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฌธ์„œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ฒƒ์€ ๋ช…ํ™•ํžˆ ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ๋Œ€์‹  ๋ฌธ์ œ๋ฅผ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ฒฐํ•ฉ ์š”์ฒญ์—์„œ ์–ด๋””์„œ ์‹œ์ž‘ํ•ด์•ผ ํ•˜๋Š”์ง€, Go, Rust ๋˜๋Š” Swift ๋ชจ๋‘ rune, Character ๋˜๋Š” Unicode Scalar( System.Rune ์— ๋Œ€ํ•œ ์ด๋ฆ„)์— ์ด๋Ÿฌํ•œ API๋ฅผ ํ‘œ์‹œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ œ์•ˆ๋œ ๊ตฌํ˜„์„ ์ œ๊ณตํ•˜์‹ญ์‹œ์˜ค.

์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ๋Š” System.Rune ์™€ ๋…๋ฆฝ์ ์œผ๋กœ ์ถ”์ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ ๊ฐ€์น˜๋ฅผ ์œ„ํ•ด Swift๋Š” ์ด๋ฅผ ์œ„ํ•ด Character ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ๋˜ํ•œ Swift๋Š” ๋ฌธ์ž์—ด์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ›Œ๋ฅญํ•œ ๋ชจ๋ธ์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์„ ์ ์ ˆํ•œ ๋ฃฌ์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์€ ์ƒ์œ„ API์— ์†ํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ustring ๊ตฌํ˜„๊ณผ ๋™์ผํ•œ ๊ธฐํŒ์„ ์‚ฌ์šฉํ•˜๋Š” System.Rune ๊ตฌํ˜„์„ ๋ณด๊ณ  ์ด๋Ÿฌํ•œ ๋ฒ„ํผ๊ฐ€ utf8 ๋ฌธ์ž์—ด์— ๋งคํ•‘๋˜๋Š” ๋ฐฉ์‹์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

https://github.com/migueldeicaza/NStack/blob/master/NStack/strings/ustring.cs

API์— System.Rune ๋ฅผ ๋„์ž…ํ•œ ์ดํ›„๋กœ ์•„์ง ์—…๋ฐ์ดํŠธํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์„œ๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

https://migueldeicaza.github.io/NStack/api/NStack/NStack.ustring.html

๋ช…๋ช…์— ๊ด€ํ•ด์„œ๋Š” ๋ถ„๋ช…ํžˆ Rust๊ฐ€ char ์—์„œ ๊ฐ€์žฅ ์ข‹์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ๋ง์ณค์Šต๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ๋กœ ์ข‹์€ ๋ฐฉ๋ฒ•์€ rune ๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. 4์ž๋ณด๋‹ค ํฌ๋ฉด ์‚ฌ๋žŒ๋“ค์ด ์˜ณ์€ ์ผ์„ ํ•˜๋Š” ๋ฐ ๋ฐฉํ•ด๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ฃ„์†ก ํ•ด์š”; CodePoint ๋Š” ์ •๋ง ์ข‹์€ ์ด๋ฆ„์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ž๋ช…ํ•˜๊ณ  ๊ธฐ์–ต์— ๋‚จ์œผ๋ฉฐ c p ๋กœ ์ž๋™ ์™„์„ฑ๋ฉ๋‹ˆ๋‹ค.

IsCombining ๋Š” ํ™•์‹คํžˆ ํ•„์š”ํ•˜์ง€๋งŒ ๊ฒฐํ•ฉ ํด๋ž˜์Šค๋ฅผ ์•„๋Š” ๊ฒƒ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋ฉฐ IsCombining ๋Š” IsCombining => CombiningClass != 0 ๋˜๋Š” IsCombining => CombiningClass != CombiningClass.None $์ด๋ฏ€๋กœ ๋Œ€๋ถ€๋ถ„ ์„คํƒ•์ž…๋‹ˆ๋‹ค. ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ๋Š” ์‹ค์ œ๋กœ ๋‹ค์‹œ ์™ธ๋ถ€์— ์žˆ์ง€๋งŒ ์ถœ๋ฐœ์ ์€ ๊ธฐ๋ณธ ํด๋Ÿฌ์Šคํ„ฐ๋ง, ์žฌ์ •๋ ฌ ๋“ฑ์„ ์œ„ํ•œ ๊ฒฐํ•ฉ ํด๋ž˜์Šค๋ฅผ ์•„๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

CodePoint ๋Š” ์ฝ”๋“œ ํฌ์ธํŠธ์— ๋Œ€ํ•œ ์œ ํ˜•์— ๋Œ€ํ•œ ํ›Œ๋ฅญํ•œ ์ด๋ฆ„์ด๋ฉฐ 4๊ฐœ์˜ ๋ฌธ์ž๋Š” ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ๋‹ค๋ฅธ ์œ ํ˜•์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ์ œํ•œ์ด ์•„๋‹™๋‹ˆ๋‹ค. string ๋Š” 50% ๋” ํฌ๋ฉฐ ์ •๊ธฐ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ๋ฐฉํ•ด๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌด์ž‘์œ„๋กœ ๋ฝ‘์€ ๋„ค ๊ธ€์ž๊ฐ€ ๋ฐ”๋‘‘์˜ ์‹ค์ˆ˜๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋‚˜์€ ์ด๋ฆ„์ผ ๊ฒƒ์ด๋‹ค.

uint ๋Š” CLS ๊ทœ๊ฒฉ์ด ์•„๋‹ˆ๋ฏ€๋กœ ์•„์ŠคํŠธ๋ž„๊ณ„๋ฅผ ๋ฎ๋Š” CLS ๊ทœ๊ฒฉ ctor๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. int ๋„ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์–‘๋ฐฉํ–ฅ ์•”์‹œ์  ๋ณ€ํ™˜์€ ๊ณผ๋ถ€ํ•˜๋กœ ์ธํ•ด ๋‚˜์œ ์ผ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ•œ ๋ฐฉํ–ฅ์€ ์•„๋งˆ๋„ ๋ช…์‹œ์ ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์–ด๋Š ๊ฒƒ์ด ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•œํŽธ์œผ๋กœ uint / int ๋Š” 0๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ 10FFFF 16 ๋ณด๋‹ค ํฐ ๊ฐ’์€ ์˜๋ฏธ๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์ฝ”๋“œ ํฌ์ธํŠธ๋ณด๋‹ค ๋” ๋„“์Šต๋‹ˆ๋‹ค. ์ˆซ์ž. ๋‹ค๋ฅธ ํ•œํŽธ์œผ๋กœ ๋‚˜๋Š” ๊ทธ ๋ฐ˜๋Œ€๋ณด๋‹ค ๋” ์ž์ฃผ ์ˆซ์ž์—์„œ ์ฝ”๋“œ ํฌ์ธํŠธ๋กœ ์บ์ŠคํŠธํ•˜๊ธฐ๋ฅผ ์›ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

uint๋Š” CLS ๊ทœ๊ฒฉ์ด ์•„๋‹ˆ๋ฏ€๋กœ ์•„์ŠคํŠธ๋ž„ ํ‰๋ฉด์„ ๋ฎ๋Š” CLS ๊ทœ๊ฒฉ ctor๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. int๋„ ํ•„์š”ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ƒˆ๋กœ์šด ๊ณ ์œ  ์œ ํ˜•์ด ๊ณต์šฉ ์–ธ์–ด์— ๋„์ž…๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.

JonHanna -- ์ด ์„ธ ๊ฐ€์ง€ ์ƒ์„ฑ์ž๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ?
๊ณต๊ฐœ ์ •์  ์•”์‹œ์  ์—ฐ์‚ฐ์ž uint(๋ฃฌ ๋ฃฌ);
๊ณต๊ฐœ ์ •์  ์•”์‹œ์  ์—ฐ์‚ฐ์ž Rune(char ch);
๊ณต๊ฐœ ์ •์  ์•”์‹œ์  ์—ฐ์‚ฐ์ž Rune(๋‹จ์œ„ ๊ฐ’);

"uint" ๋Œ€์‹  "int"์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. AFAICT, int๋Š” ์ „์ฒด ์•„์ŠคํŠธ๋ž„(๋น„ BMP) ํ‰๋ฉด ์„ธํŠธ๋ฅผ ์‰ฝ๊ฒŒ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

@PeterSmithRedmond ๋‚ด ๋ง์€ ๋‘ ๊ฐœ์˜ ์ƒ์„ฑ์ž๋ฟ๋งŒ ์•„๋‹ˆ๋ผ char ๋ฅผ ์ทจํ•˜๋Š” ์ƒ์„ฑ์ž์™€ uint ๋ฅผ ์ทจํ•˜๋Š” ์ƒ์„ฑ์ž๊ฐ€ ์žˆ์–ด์•ผ ํ•˜๊ณ , int ๋ฅผ ์ทจํ•˜๋Š” ์ƒ์„ฑ์ž๊ฐ€ ์žˆ์–ด์•ผ ํ•˜์ง€๋งŒ, ๋ฌผ๋ก  int ๋„ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. implicit ๋Š” ๋ฌด์—‡์ด๊ณ  explicit ๋Š” ๋˜ ๋‹ค๋ฅธ ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค). uint ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์–ธ์–ด์— ๋Œ€ํ•ด์„œ๋„ ์•„๋ฌด๋Ÿฐ ํ•ด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๊ฒฐ๊ตญ ์•„์ฃผ ์ž์—ฐ์Šค๋Ÿฌ์šด ๊ฒฝ๊ธฐ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด System.Char๋ฅผ ๋Œ€์ฒดํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ "์‚ฐ์ˆ "์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฉฐ(์ฆ‰, +, -, *, /์—์„œ ==, !=, >, < ํ™•์‹คํ•˜์ง€ ์•Š์Œ) ๋” ์ค‘์š”ํ•˜๊ฒŒ๋Š” ์ด๊ฒƒ์˜ ๋ฆฌํ„ฐ๋Ÿด์„ ์ง€์›ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์“ธ ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

rune r = '๐ˆ'; // Ostrogothic character chose on purpose as in UTF16 will be a "surrogate pairs"


image

rune ๊ฐ€ ์•„๋‹ˆ๋ฉด ์ž‘๋™ํ•  ์ˆ˜ ์žˆ๋Š” character ์˜ ๋‹ค๋ฅธ ๋™์˜์–ด๋งŒ letter ์ž…๋‹ˆ๊นŒ?

๋ช…์‚ฌ

  1. ์‚ฌ๋žŒ์ด๋‚˜ ์กฐ์ง์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ์„œ๋ฉด ๋˜๋Š” ์ธ์‡„๋œ ํ†ต์‹ ์œผ๋กœ ์ผ๋ฐ˜์ ์œผ๋กœ ์šฐํŽธ์œผ๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.
  2. ๋ง์†Œ๋ฆฌ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด ์ผ๋ฐ˜์ ์œผ๋กœ ์“ฐ๊ธฐ ๋ฐ ์ธ์‡„์— ์‚ฌ์šฉ๋˜๋ฉฐ ์•ŒํŒŒ๋ฒณ์˜ ์ผ๋ถ€์ธ ๊ธฐํ˜ธ ๋˜๋Š” ๋ฌธ์ž.
  3. ๊ทธ๋Ÿฌํ•œ ๊ธฐํ˜ธ๋‚˜ ๋ฌธ์ž๊ฐ€ ํฌํ•จ๋œ ์ธ์‡„ ์œ ํ˜•์˜ ์กฐ๊ฐ.

๊ทธ๊ฒƒ์ด ๋ฌธ์ž ๋Œ€ ์ˆซ์ž์™€ ์ถฉ๋Œํ•˜์ง€๋งŒ

Letter๋Š” ๋ฃฌ๋ณด๋‹ค ์œ ๋‹ˆ์ฝ”๋“œ(์ผ๋ฐ˜์ ์œผ๋กœ Net)์—์„œ ํ›จ์”ฌ ๋” ์ •ํ™•ํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ œ ์ƒ๊ฐ์—๋Š” ์ด๊ฒƒ์„ ์œ ๋‹ˆ์ฝ”๋“œ ๋ฌธ์ž ์œ ํ˜•์œผ๋กœ ๋งŒ๋“ค๋ ค๋ฉด ์œ ๋‹ˆ์ฝ”๋“œ์˜ ๋ช…๋ช… ๊ทœ์น™์„ ๋”ฐ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” _"์ฝ”๋“œ ํฌ์ธํŠธ"_๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์ฝ”๋“œ ํฌ์ธํŠธ . (1) ์œ ๋‹ˆ์ฝ”๋“œ ์ฝ”๋“œ์ŠคํŽ˜์ด์Šค์˜ ๋ชจ๋“  ๊ฐ’ ์ฆ‰, 0์—์„œ 10FFFF16 ์‚ฌ์ด์˜ ์ •์ˆ˜ ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค. ( ์„น์…˜ 3.4, ๋ฌธ์ž ๋ฐ ์ธ์ฝ”๋”ฉ์˜ ์ •์˜ D10 ์ฐธ์กฐ) ๋ชจ๋“  ์ฝ”๋“œ ํฌ์ธํŠธ๊ฐ€ ์ธ์ฝ”๋”ฉ๋œ ๋ฌธ์ž์— ํ• ๋‹น๋˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ฝ”๋“œ ํฌ์ธํŠธ ์œ ํ˜• ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. (2) ์ฝ”๋“œํ™”๋œ ๋ฌธ์ž ์ง‘ํ•ฉ์—์„œ ๋ฌธ์ž์˜ ๊ฐ’ ๋˜๋Š” ์œ„์น˜.

์•„๋‹ˆ๋ฉด ๊ทธ๋ƒฅ ํฌ๊ธฐํ•˜๊ณ  ์˜ค๋ฆฌ๋ฅผ "์˜ค๋ฆฌ"๋ผ๊ณ  ๋ถ€๋ฅด๊ณ  ์œ ๋‹ˆ์ฝ”๋“œ ๋ฌธ์ž( uchar ๋ผ๊ณ ๋„ ํ•จ)๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

๋Œ€์‹  System.CodePoint ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ์•Š์œผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?
Imho ๊ทธ๊ฒƒ์€ ์œ ๋‹ˆ ์ฝ”๋“œ์˜ ์šฉ์–ด ์ธก๋ฉด์—์„œ ๋” ์ ์ ˆํ•˜๋ฉฐ Java ์„ธ๊ณ„์˜ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์šฉ์–ด๋ฅผ ๋”ฐ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ์œ ๋‹ˆ์ฝ”๋“œ ์šฉ์–ด๋ฅผ ๋”ฐ๋ฅด๋„๋ก ํ•ฉ์‹œ๋‹ค. .NET์˜ ๋ฌธ์ž์—ด์ด char ์ปฌ๋ ‰์…˜์ด๊ณ  ์ด char ์ปฌ๋ ‰์…˜์ด ์œ ๋‹ˆ์ฝ”๋“œ ๊ธฐ๋ฐ˜์ด๋ผ๋Š” ์‚ฌ์‹ค์„ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— .NET์˜ ์ผ๋ฐ˜ ๋ฌธ์ž ๋ฐ ๋ฌธ์ž์—ด ๊ตฌํ˜„ ์ธก๋ฉด์—์„œ ๋” ํ•ฉ๋ฆฌ์ ์ด๊ณ  ๋ณดํŽธ์ ์ž…๋‹ˆ๋‹ค.

์ €๋Š” Java์™€ .NET ์„ธ๊ณ„์—์„œ ๋ชจ๋‘ ์‚ด์•„์™”๊ธฐ ๋•Œ๋ฌธ์— ์••๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์— ๋Œ€ํ•œ ์ดˆ์•ˆ ๊ตฌํ˜„์„ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ ์ด๊ฒƒ์—๋Š” ๋‘ ๊ฐ€์ง€ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์žˆ์œผ๋ฉฐ ๋‘˜ ๋‹ค ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค(@GrabYourPitchforks์˜ https://github.com/dotnet/corefxlab/issues/1799์˜ CodeUnit)

C# keyword      Ugly Long form      Size
----------------------------------------
ubyte      <=>  System.CodeUnit    8 bit  - Assumed Utf8 in absence of encoding param
uchar      <=>  System.CodePoint  32 bit

CodeUnit / ubyte ๋Š” ๊ฐ€๋ณ€ ๋„ˆ๋น„ ์ธ์ฝ”๋”ฉ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐ ์ค‘์š”ํ•˜๊ณ  Span<ubyte> ์—์„œ ์‚ฌ์šฉํ•˜์—ฌ ํ…์ŠคํŠธ API๊ฐ€ ์›์‹œ ๋ฐ”์ดํŠธ๊ฐ€ ์•„๋‹Œ ํ…์ŠคํŠธ ์œ ํ˜•์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•˜๋Š” ๋ฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

CodePoint / uchar ๋Š” ํ•ฉ๋ฆฌ์ ์ธ ์ฒ˜๋ฆฌ์— ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด .IndexOf(โค) as ubyte ์ž์ฒด๋Š” ๋ฉ€ํ‹ฐ๋ฐ”์ดํŠธ ์œ ๋‹ˆ์ฝ”๋“œ ๋ฌธ์ž๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ubyte s ์ด์ƒ์„ ์—ด๊ฑฐํ•˜๋Š” ๊ฒƒ์€ ์œ„ํ—˜ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์—ด๊ฑฐ์ž๋Š” uchar ๋‹จ์œ„๋กœ ์ž‘๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‘ ์ œ์•ˆ์„ ๊ฒฐํ•ฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

using System;
using System.Runtime.InteropServices;

// C# Keywords
using ubyte = System.CodeUnit;
using uchar = System.CodePoint;
using uspan = System.Utf8Span;
using ustring = System.Utf8String;

namespace System
{
    public ref struct Utf8Span
    {
        private readonly ReadOnlySpan<ubyte> _buffer;

        public Utf8Span(ReadOnlySpan<ubyte> span) => _buffer = span;
        public Utf8Span(uspan span) => _buffer = span._buffer;
        public Utf8Span(ustring str) => _buffer = ((uspan)str)._buffer;
        public Utf8Span(ReadOnlyMemory<ubyte> memory) => _buffer = memory.Span;

        // Returns the CodeUnit index, not CodePoint index
        public int IndexOf(char value) => IndexOf(value, 0);
        public int IndexOf(char value, int startIndex) => IndexOf(value, 0, _buffer.Length);
        public int IndexOf(char value, int startIndex, int count);
        public int IndexOf(char value, StringComparison comparisonType);

        public int IndexOf(uchar value) => IndexOf(value, 0);
        public int IndexOf(uchar value, int startIndex) => IndexOf(value, 0, _buffer.Length);
        public int IndexOf(uchar value, int startIndex, int count);
        public int IndexOf(uchar value, StringComparison comparisonType);

        public uspan Substring(int codeUnitIndex);
        public uspan Substring(int codeUnitIndex, int codePointCount);

        public bool StartsWith(uchar ch) => _buffer.Length >= 1 && _buffer[0] == ch;
        public bool StartsWith(ustring str) => StartsWith((uspan)str);
        public bool StartsWith(uspan value) => _buffer.StartsWith(value._buffer);
        public bool EndsWith(uchar ch) => _buffer.Length >= 1 && _buffer[0] == ch;
        public bool EndsWith(ustring str) => EndsWith((uspan)str);
        public bool EndsWith(uspan value) => _buffer.EndsWith(value._buffer);

        public Enumerator GetEnumerator() => new Enumerator(this);

        // Iterates in uchar steps, not ubyte steps
        public ref struct Enumerator
        {
            public Enumerator(uspan span);

            public uchar Current;
            public bool MoveNext();
            public void Dispose() { }
            public void Reset() => throw new NotSupportedException();
        }
    }

    public class Utf8String
    {
        private readonly ReadOnlyMemory<ubyte> _buffer;

        public Utf8String(ustring str) => _buffer = str._buffer;
        public Utf8String(ReadOnlyMemory<ubyte> memory) => _buffer = memory;

        public bool StartsWith(uchar ch) => ((uspan)this).StartsWith(ch);
        public bool StartsWith(ustring value) => ((uspan)this).StartsWith(value);
        public bool StartsWith(uspan value) => ((uspan)this).StartsWith(value);
        public bool EndsWith(uchar ch) => ((uspan)this).EndsWith(ch);
        public bool EndsWith(ustring value) => ((uspan)this).EndsWith(value);
        public bool EndsWith(uspan value) => ((uspan)this).EndsWith(value);

        public static implicit operator uspan(ustring value) => new uspan(value._buffer);

        // Returns the CodeUnit index, not CodePoint index
        public int IndexOf(char value) => IndexOf(value, 0);
        public int IndexOf(char value, int startIndex) => IndexOf(value, 0, _buffer.Length);
        public int IndexOf(char value, int startIndex, int count);
        public int IndexOf(char value, StringComparison comparisonType);

        public int IndexOf(uchar value) => IndexOf(value, 0);
        public int IndexOf(uchar value, int startIndex) => IndexOf(value, 0, _buffer.Length);
        public int IndexOf(uchar value, int startIndex, int count);
        public int IndexOf(uchar value, StringComparison comparisonType);

        public ustring Substring(int codeUnitIndex);
        public ustring Substring(int codeUnitIndex, int codePointCount);

        public uspan.Enumerator GetEnumerator() => ((uspan)this).GetEnumerator();
    }

    [StructLayout(LayoutKind.Auto, Size = 1)]
    public struct CodeUnit : IComparable<ubyte>, IEquatable<ubyte>
    {
        private readonly byte _value;

        public CodeUnit(ubyte other) => _value = other._value;
        public CodeUnit(byte b) => _value = b;

        public static bool operator ==(ubyte a, ubyte b) => a._value == b._value;
        public static bool operator !=(ubyte a, ubyte b) => a._value != b._value;
        public static bool operator <(ubyte a, ubyte b) => a._value < b._value;
        public static bool operator <=(ubyte a, ubyte b) => a._value <= b._value;
        public static bool operator >(ubyte a, ubyte b) => a._value > b._value;
        public static bool operator >=(ubyte a, ubyte b) => a._value >= b._value;

        public static implicit operator byte(ubyte value) => value._value;
        public static explicit operator ubyte(byte value) => new ubyte(value);

        // other implicit conversions go here
        // if intrinsic then casts can be properly checked or unchecked

        public int CompareTo(ubyte other) => _value.CompareTo(other._value);

        public override bool Equals(object other) => (other is ubyte cu) && (this == cu);

        public bool Equals(ubyte other) => (this == other);

        public override int GetHashCode() => _value;

        public override string ToString() => _value.ToString();
    }

    [StructLayout(LayoutKind.Auto, Size = 4)]
    public struct CodePoint : IComparable<uchar>, IEquatable<uchar>
    {
        private readonly uint _value;

        public CodePoint(uint CodePoint);
        public CodePoint(char ch);

        public static ValueTuple<uchar, int> DecodeLastCodePoint(ubyte[] buffer, int end);
        public static ValueTuple<uchar, int> DecodeLastCodePoint(ustring str, int end);
        public static ValueTuple<uchar, int> DecodeCodePoint(ubyte[] buffer, int start, int n);
        public static ValueTuple<uchar, int> DecodeCodePoint(ustring str, int start, int n);
        public static int EncodeCodePoint(uchar CodePoint, ubyte[] dest, int offset);
        public static bool FullCodePoint(ubyte[] p);
        public static bool FullCodePoint(ustring str);
        public static int InvalidIndex(ubyte[] buffer);
        public static int InvalidIndex(ustring str);
        public static bool IsControl(uchar CodePoint);
        public static bool IsDigit(uchar CodePoint);
        public static bool IsGraphic(uchar CodePoint);
        public static bool IsLetter(uchar CodePoint);
        public static bool IsLower(uchar CodePoint);
        public static bool IsMark(uchar CodePoint);
        public static bool IsNumber(uchar CodePoint);
        public static bool IsPrint(uchar CodePoint);
        public static bool IsPunctuation(uchar CodePoint);
        public static bool IsSpace(uchar CodePoint);
        public static bool IsSymbol(uchar CodePoint);
        public static bool IsTitle(uchar CodePoint);
        public static bool IsUpper(uchar CodePoint);
        public static int CodePointCount(ubyte[] buffer, int offset, int count);
        public static int CodePointCount(ustring str);
        public static int CodePointLen(uchar CodePoint);
        public static uchar SimpleFold(uchar CodePoint);
        public static uchar To(Case toCase, uchar CodePoint);
        public static uchar ToLower(uchar CodePoint);
        public static uchar ToTitle(uchar CodePoint);
        public static uchar ToUpper(uchar CodePoint);
        public static bool Valid(ubyte[] buffer);
        public static bool Valid(ustring str);
        public static bool ValidCodePoint(uchar CodePoint);

        public static bool operator ==(uchar a, uchar b) => a._value == b._value;
        public static bool operator !=(uchar a, uchar b) => a._value != b._value;
        public static bool operator <(uchar a, uchar b) => a._value < b._value;
        public static bool operator <=(uchar a, uchar b) => a._value <= b._value;
        public static bool operator >(uchar a, uchar b) => a._value > b._value;
        public static bool operator >=(uchar a, uchar b) => a._value >= b._value;

        // etc
    }
}

๋‚ด ํ”„๋กœํ† ํƒ€์ž… ๊ตฌํ˜„์—์„œ UnicodeScalar ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์œ ๋‹ˆ์ฝ”๋“œ ์Šค์นผ๋ผ ๊ฐ’(U+0000..U+10FFFF ๋ฒ”์œ„์˜ ๊ฐ’ ํฌํ•จ, ๋Œ€๋ฆฌ ์ฝ”๋“œ ํฌ์ธํŠธ ์ œ์™ธ) ๋ฐ Utf8Char UTF-8 ์ฝ”๋“œ ๋‹จ์œ„๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด _UnicodeScalar_ ๋Œ€์‹  _Rune_์„ ์„ ํ˜ธํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ณ„๋กœ ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์ง€๋งŒ "์œ ๋‹ˆ์ฝ”๋“œ ์Šค์นผ๋ผ ๊ฐ’"์ด๋ผ๋Š” ์šฉ์–ด ๋Š” ์œ ๋‹ˆ์ฝ”๋“œ ์‚ฌ์–‘์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์šฉ์–ด์ž„์„ ์ง€์ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ;)

.NET Framework์—๋Š” ๊ฒฐํ•ฉ๋  ๋•Œ ๋ถ„ํ• ํ•  ์ˆ˜ ์—†๋Š” ๋‹จ์ผ ๋ฌธ์ž์†Œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ ์Šค์นผ๋ผ์ธ "ํ…์ŠคํŠธ ์š”์†Œ"๋ผ๋Š” ๊ฐœ๋…๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์ •๋ณด ๋Š” MSDN ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ํŠนํžˆ ๋ฌธ์ž์—ด์„ ์—ด๊ฑฐํ•  ๋•Œ ์ฝ”๋“œ ๋‹จ์œ„( Utf8Char ๋˜๋Š” Char ), ์Šค์นผ๋ผ ๊ฐ’( UnicodeScalar ) ๋˜๋Š” ํ…์ŠคํŠธ ์š”์†Œ๋ณ„๋กœ ์—ด๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠน์ • ์‹œ๋‚˜๋ฆฌ์˜ค. ์ด์ƒ์ ์œผ๋กœ๋Š” String๊ณผ Utf8String ๋ชจ๋‘์—์„œ ์„ธ ๊ฐ€์ง€ ์œ ํ˜•์„ ๋ชจ๋‘ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœํ† ํƒ€์ž…์— ๋Œ€ํ•œ API ํ‘œ๋ฉด์€ ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜์œผ๋ฉฐ ๋น ๋ฅด๊ฒŒ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์ง€๋งŒ https://github.com/dotnet/corefxlab/tree/utf8string/src/System.Text.Utf8/System ์—์„œ ํ˜„์žฌ ์ƒ๊ฐ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/dotnet/corefxlab/blob/master/src/System.Text.Primitives/System/Text/Encoders/Utf8Utility.cs.

์•ฝ๊ฐ„ ์ฃผ์ œ์—์„œ ๋ฒ—์–ด๋‚จ:
"ํ…์ŠคํŠธ ์š”์†Œ" ๋Š” UAX dotnet/corefx#29์˜ "Grapheme Cluster Boundaries"์— ์˜ํ•ด ์ •์˜๋œ ๋ถ„ํ• ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        var e = StringInfo.GetTextElementEnumerator("๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ‘ฆ๐Ÿผ๐Ÿ‘จ๐Ÿฝโ€๐Ÿ‘ฆ๐Ÿพโ€๐Ÿ‘ฆ๐Ÿฟ๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ‘จ๐Ÿฝโ€๐Ÿ‘ฆ๐Ÿผโ€๐Ÿ‘ง๐Ÿฝ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿ‘ง๐Ÿผโ€๐Ÿ‘ง๐Ÿพ");
        while (e.MoveNext())
        {
            Console.WriteLine(e.GetTextElement());
        }
    }
}

์˜ˆ์ƒ ๊ฒฐ๊ณผ:
๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ‘ฆ๐Ÿผ
๐Ÿ‘จ๐Ÿฝโ€๐Ÿ‘ฆ๐Ÿพโ€๐Ÿ‘ฆ๐Ÿฟ
๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ‘จ๐Ÿฝโ€๐Ÿ‘ฆ๐Ÿผโ€๐Ÿ‘ง๐Ÿฝ
๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿ‘ง๐Ÿผโ€๐Ÿ‘ง๐Ÿพ

์‹ค์ œ ๊ฒฐ๊ณผ:
๐Ÿ‘ฉ
๐Ÿป
โ€
๐Ÿ‘ฆ
๐Ÿผ
๐Ÿ‘จ
๐Ÿฝ
โ€
๐Ÿ‘ฆ
๐Ÿพ
โ€
๐Ÿ‘ฆ
๐Ÿฟ
๐Ÿ‘ฉ
๐Ÿผ
โ€
๐Ÿ‘จ
๐Ÿฝ
โ€
๐Ÿ‘ฆ
๐Ÿผ
โ€
๐Ÿ‘ง
๐Ÿฝ
๐Ÿ‘ฉ
๐Ÿป
โ€
๐Ÿ‘ฉ
๐Ÿฟ
โ€
๐Ÿ‘ง
๐Ÿผ
โ€
๐Ÿ‘ง
๐Ÿพ

UnicodeScalar ๋Š” ์—ฌ์ „ํžˆ ์ž…๋ ฅํ•˜๊ธฐ ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. u s c ์ŠคํŽ˜์ด์Šค (์ž๋™ ์™„์„ฑ) ๊ทธ๊ฒƒ์ด ์ •ํ™•ํ•˜๊ณ  ๊ฐ€์žฅ ์ž๊ธฐ ์„ค๋ช…์ ์ธ ์šฉ์–ด์ด๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๊ฒƒ์„ ์–ป๊ธฐ๋ฅผ ์ •๋ง๋กœ ๋ฐ”๋ž๋‹ˆ๋‹ค.

@ufcpp ์ข‹์€ ์ง€์ ์ž…๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด ๋ฌธ์ œ๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์—ฌ์‹ญ์‹œ์˜ค. ํ˜ธํ™˜์„ฑ ์ด์œ ๋กœ ๋™์ž‘์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค๋ฉด ํ•ด๋‹น ์œ ํ˜•์„ ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์–‘์„ ์ค€์ˆ˜ํ•˜๋Š” ์ž์†Œ ์—ด๊ฑฐ์ž๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

ubyte / uchar ์€(๋Š”) ํ˜ผ๋ž€์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ushort / uint / ulong ๋กœ ์„ค์ •๋œ ๊ทœ์น™์— ๋”ฐ๋ผ unsigned char / unsigned byte ์ฒ˜๋Ÿผ ์ฝ์Šต๋‹ˆ๋‹ค. char8 / u8char ๋ฐ char32 / u32char ๊ฐ€ ๋” ๋ช…ํ™•ํ• ๊นŒ์š”?

์–ด์จŒ๋“  UTF-8 ์ฝ”๋“œ ๋‹จ์œ„ ๋ฐ ์ฝ”๋“œ ํฌ์ธํŠธ๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์€์ง€ ์—ฌ๋ถ€์— ๋Œ€ํ•ด ์ž˜๋ชป ์ •๋ ฌ๋˜์–ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

  1. byte , int ์™€ ๊ฐ™์€ .NET์˜ ์ €์ˆ˜์ค€ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ์œ ํ˜•
  2. DateTime , Guid ์™€ ๊ฐ™์€ ๊ธฐ์กด ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ๋กœ/์—์„œ ๋ณ€ํ™˜ํ•  ๋ฐ์ดํ„ฐ ํ˜•์‹

๊ทธ๋Ÿฐ ๋‹ค์Œ ํ•ด๋‹น ๊ฒฐ์ •์— ๋”ฐ๋ผ ์ฝ”๋“œ ํฌ์ธํŠธ ๊ด€๋ จ API๋ฅผ ์–ด๋–ป๊ฒŒ ๋…ธ์ถœํ•ฉ๋‹ˆ๊นŒ?

์˜ต์…˜ 1์€ C++17๊ณผ ๊ฐ™์ด char8, char16 ๋ฐ char32 ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ(๋ฐ ์ˆ˜๋ฐ˜๋˜๋Š” u8string, u16string ๋ฐ u32string)๋ฅผ ํ†ตํ•ด ํ…์ŠคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ rune ์ธ char32๋Š” ์ž˜๋ชป๋œ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ char16์ด char ์ด๊ณ  char8 ์— ๋Œ€ํ•œ ์„ธ ๋ฒˆ์งธ ์ด๋ฆ„๋„ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์˜ต์…˜ 2๋Š” byte ๋ฐ int/uint๊ฐ€ UTF ์ฝ”๋“œ ๋‹จ์œ„ ๋ฐ ์ฝ”๋“œ ํฌ์ธํŠธ๋ฅผ ์ €์žฅํ•˜๊ธฐ์— '์ถฉ๋ถ„ํžˆ' ์ข‹๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ชจ๋“  ๋ฌธ์ž์—ด์ด UTF-16์œผ๋กœ ์œ ์ง€๋จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. CodePoint / rune ๋Š” ์ด์ง„ ํ‘œํ˜„์ด ์•„๋‹Œ Code Point ์˜๋ฏธ๋ก ์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐ ํ•˜๋ฉฐ IO์šฉ์ด ์•„๋‹™๋‹ˆ๋‹ค .

IMO UTF-8/UTF-32๋Š” ๋ฐ์ดํ„ฐ ํ˜•์‹์ผ ๋ฟ์ž…๋‹ˆ๋‹ค(์˜ต์…˜ 2). ๋ฐ์ดํ„ฐ(byte/int)๋กœ ์ทจ๊ธ‰ํ•˜์‹ญ์‹œ์˜ค. CodePoint ๋Š” $#$ int $#$๋ณด๋‹ค DateTime ๋˜๋Š” Guid (๋‹ค๋ฅธ ์‹๋ณ„์ž*)์™€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. ์ €์ˆ˜์ค€ ๊ธฐ๋ณธ ์œ ํ˜•์ด ์•„๋‹ˆ๋ฉฐ IO์—์„œ ์ง์ ‘ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (์ฆ‰, BinaryWriter) ๋‚ด์žฅ ํ•จ์ˆ˜๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@miyu corefxlab ์—์„œ ๊ฐ€์ ธ์˜ฌ ํ”„๋กœํ† ํƒ€์ž…์€ ์˜ต์…˜ 1์— ๋” ๊ฐ€๊น์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ ๋‹จ์œ„๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํŠน์ • ๋ฐ์ดํ„ฐ ์œ ํ˜•์ด ์žˆ์œผ๋ฉฐ ์ด๋Ÿฌํ•œ ๋ฐ์ดํ„ฐ ์œ ํ˜•์€ ํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ์˜ ๋‚ด๋ถ€ ํ‘œํ˜„์„ ์œ„ํ•œ ๊ฒƒ์ด๋ฉฐ ์œ ์„ ์„ ํ†ตํ•ด ํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. (๋‹น์‹ ์ด ์ง€์ ํ–ˆ๋“ฏ์ด .NET์€ ์˜ค๋Š˜๋‚  ์ด๋ฏธ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. System.Char ๋Š” UTF-16 ๋ฌธ์ž์—ด์˜ ์ฝ”๋“œ ๋‹จ์œ„์ด์ง€๋งŒ System.Char ๋Š” ์œ ์„ ์œผ๋กœ ๋ณด๋‚ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.)

๋˜ํ•œ byte[] / Span<byte> / ๋“ฑ(๋ชจ๋“  ๋ฐ์ดํ„ฐ์˜ ์ด์ง„ ํ‘œํ˜„์ด๋ฉฐ I/O์— ์ ํ•ฉ)๊ณผ Utf8String ์™€ ๊ฐ™์€ ๊ธฐ๋ณธ ์œ ํ˜• ๊ฐ„์— ๋ณ€ํ™˜ํ•˜๋Š” API๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. String / Guid / etc. ์ด๋“ค ์ค‘ ์ผ๋ถ€๋Š” ๋‹ค๋ฅธ ๊ฒƒ๋ณด๋‹ค ๋” ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, i/o์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ReadOnlySpan<byte> ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํŽธ๋ฆฌํ•œ Utf8String.Bytes ์†์„ฑ์„ ๋…ธ์ถœํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด ์†์„ฑ getter๋Š” O(1) ๋ณต์žก์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. String ์œ ํ˜•์—๋Š” ์ด๋Ÿฌํ•œ ์†์„ฑ์„ ๋„์ž…ํ•˜์ง€ ์•Š๊ฒ ์ง€๋งŒ String.ToUtf8Bytes() ํŽธ์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•  ์ˆ˜๋Š” ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Utf8String.Bytes ์†์„ฑ์ด ์žˆ๋”๋ผ๋„ Utf8String ์ธ์Šคํ„ด์Šค๋ฅผ ์ง์ ‘ ์—ด๊ฑฐํ•˜๋Š” ์š”์†Œ ์œ ํ˜•์€ byte ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. Utf8CodeUnit (์ด๋ฆ„ ๋ฏธ์ •) ๋˜๋Š” UnicodeScalar ์ค‘ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋นŒ๋“œํ•˜๋ ค๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ์œ ํ˜•์— ๋” ์ ํ•ฉํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฐ”๋ณด ๊ฐ™์€ ์•„์ด๋””์–ด - wchar (_wide char_)๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ์˜ค๋Š˜๋‚  ๋Œ€๋ถ€๋ถ„์˜ C ๋ฐ C++ ์ปดํŒŒ์ผ๋Ÿฌ ํ™˜๊ฒฝ(Windows ์™ธ๋ถ€)์€ ์ด๋ฏธ wchar_t ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 32๋น„ํŠธ ์ฝ”๋“œ ๋‹จ์œ„์— ํ•ด๋‹นํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. Windows๋Š” wchar_t ๊ฐ€ 16๋น„ํŠธ ์œ ํ˜•์œผ๋กœ ์ •์˜๋œ ์ฃผ๋ชฉํ•  ๋งŒํ•œ ์˜ˆ์™ธ์ด์ง€๋งŒ ์˜ค๋Š˜๋‚  Windows์—์„œ p/invokeํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋Š” ์ด๋ฏธ .NET char ๊ฐ„์˜ ๋น„ํŠธ ๋„ˆ๋น„ ์ฐจ์ด๋ฅผ ์ธ์‹ํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. char .

type/keyword wchar ๋Š” ์šฐ๋ฆฌ์˜ ๋ช…๋ช… ๊ทœ์น™์„ ์œ„๋ฐ˜ํ•˜์ง€๋งŒ ๊ณ ๋ ค๋ฅผ ์œ„ํ•ด ์ด๊ฒƒ์„ ๋˜์กŒ์Šต๋‹ˆ๋‹ค.

์–ด๋ฆฌ์„์€ ์•„์ด๋””์–ด - wchar (์™€์ด๋“œ ๋ฌธ์ž)๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ•œ๋‹ค

์œ ํ˜• / ํ‚ค์›Œ๋“œ wchar ๋Š” ๋ช…๋ช… ๊ทœ์น™์„ ์œ„๋ฐ˜ํ•ฉ๋‹ˆ๋‹ค. ...

์งง์€ C# ์–ธ์–ด ํ‚ค์›Œ๋“œ๋ฅผ ์–ป์„ ๊ฒƒ ๊ฐ™์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

https://github.com/dotnet/apireviews/pull/64#discussion_r196962756 ์ด๋Ÿฌํ•œ ์œ ํ˜•์— ๋Œ€ํ•œ ์–ธ์–ด ํ‚ค์›Œ๋“œ๋ฅผ ๋„์ž…ํ•  ๊ฐ€๋Šฅ์„ฑ์€ ๊ทนํžˆ ๋‚ฎ์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์œ ํ˜•์€ ๋ฌธ๋งฅ์ ์ด์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค(์ฆ‰, ํ‚ค์›Œ๋“œ๊ฐ€ ๋‚˜ํƒ€๋‚ด๋Š” ์œ ํ˜•์ด ์•„๋‹ˆ๋ผ ํ•ด๋‹น ์œ ํ˜•์— ๋ฐ”์ธ๋”ฉํ•ด์•ผ ํ•˜๋Š” ํ‚ค์›Œ๋“œ์˜ ์ด๋ฆ„).

๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๊ฐ€ ์ข‹์€ ๊ฒƒ์„ ์›ํ•œ๋‹ค๋ฉด... ์˜ˆ๋ฅผ ๋“ค์–ด NotLotsOfCapitalFullWords ...

๋‚˜๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ .NET์˜ ๋ช…๋ช… ๊ทœ์น™์„ ์ข‹์•„ํ•˜์ง€๋งŒ ๊ธด ์ด๋ฆ„์€ ๋ณธ์งˆ์ ์œผ๋กœ ์ œ๋„ค๋ฆญ ๋ฐ ๋ฃจํ”„ ๋ณ€์ˆ˜๋กœ๋„ ์‚ฌ์šฉ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” int ์— ๋Œ€ํ•ด ์•ฝ๊ฐ„ ๊ณต๊ฒฉ์ ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ฌด๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค

foreach (Int32 i in list)
{
    // ...
}

๊ทธ๋“ค์€ ํ• ? (ํ™•์‹คํžˆ...)

foreach (UnicodeScalar us in str)
{
    // ...
}

ํ›จ์”ฌ ๋” ๋‚˜์˜๋‹ค

foreach (wchar c in str)
{
    // ...
}

๊ดœ์ฐฎ์•„ ๋ณด์ด๋Š”๋ฐ...

rune , wchar ๋ฐ uchar (๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์ œ์•ˆ๋จ) ๋ชจ๋‘ ๋‚˜์—๊ฒŒ ์ข‹๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. string ์˜ ๋™๋ฃŒ๋ฅผ ์œ„ํ•œ ์ œ์•ˆ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๊นŒ? wstring , ustring ๋˜๋Š” ๊ธฐํƒ€?

... C# ์–ธ์–ด ํ‚ค์›Œ๋“œ๋ฅผ ์–ป์ง€ ๋ชปํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋ฌผ๋ก , ์ฒซ ๋ฒˆ์งธ ๋ฆด๋ฆฌ์Šค์— ํ‚ค์›Œ๋“œ๊ฐ€ ์—†๋Š” ๊ฒƒ์€ ์˜๋ฏธ๊ฐ€ ์žˆ์ง€๋งŒ, ์ด๊ฒƒ์ด ๋ฏธ๋ž˜์˜ ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ด๋ผ๋ฉด ํ‚ค์›Œ๋“œ๊ฐ€ ์—†๋Š” ๊ฒƒ์€ ์ •์งํ•˜์ง€ ์•Š์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ฑ„ํƒ์— ๋Œ€ํ•ด ๋ช…๋ฐฑํžˆ ์ ๋Œ€์ ์ž…๋‹ˆ๋‹ค.

/CC @MadsTorgersen @jaredpar

C# ์–ธ์–ด ํ‚ค์›Œ๋“œ๋ฅผ ์–ป์ง€ ๋ชปํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ƒˆ ํ‚ค์›Œ๋“œ๋Š” 100% ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊นจ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ๋‹จ์–ด๋ฅผ ์„ ํƒํ•˜๋“  ํ”„๋กœ์ ํŠธ์˜ ๋ชจ๋“  ๊ณณ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ด๋ฆ„ ์œ ํ˜•์„ ๊ฐ€์ง„ ํšŒ์‚ฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ๊ฐ€์ง„ ์œ ์ผํ•œ ์˜ต์…˜์€ ๋ฌธ๋งฅ ํ‚ค์›Œ๋“œ์ž…๋‹ˆ๋‹ค: ์˜ˆ๋ฅผ ๋“ค์–ด var .

๋‚˜๋Š” ์ด๊ฒƒ์„ ์œ„ํ•ด ๋ฌธ๋งฅ ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์—‡๊ฐˆ๋ฆฐ ๊ฐ์ •์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด ์œ ํ˜• ํ‚ค์›Œ๋“œ( int , string ๋“ฑ ...)๋Š” ์‹ค์ œ ์œ ํ˜• ์ด๋ฆ„( Int32 , String )๋ณด๋‹ค ๊ตฌ์ฒด์ ์ธ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • string : ์ด๊ฒƒ์€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ corelib๋กœ ์‹๋ณ„ํ•˜๋Š” ์–ด์…ˆ๋ธ”๋ฆฌ์˜ System.String ์œ ํ˜•์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ด ์ด๋ฆ„์—๋Š” ๊ด€๋ จ๋œ ๋ชจํ˜ธ์„ฑ์ด ์—†์Šต๋‹ˆ๋‹ค.
  • String : ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ด ์œ ํ˜•์„ ์ „ํ˜€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹ค๋ฅธ ๊ฒƒ๊ณผ ๊ฐ™์€ ์œ ํ˜•์ด๋ฉฐ ์ •์˜ํ•œ ์œ ํ˜•๊ณผ ๋™์ผํ•œ ์กฐํšŒ ๊ทœ์น™์„ ๋ชจ๋‘ ๊ฑฐ์นฉ๋‹ˆ๋‹ค. string ์™€ ๊ฐ™์„ ์ˆ˜๋„ ์žˆ๊ณ  ๊ทธ๋ ‡์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— ๋ฌธ๋งฅ ํ‚ค์›Œ๋“œ๋ฅผ ๋„์ž…ํ•˜๋ฉด rune ๋Š” ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • corelib ์–ด์…ˆ๋ธ”๋ฆฌ ๋‚ด๋ถ€์˜ System.Rune ์œ ํ˜•
  • 2๋…„ ์ „์— Go ์— ๋Œ€ํ•ด ์ฝ์„ ๋•Œ ์ •์˜ํ•œ rune ์œ ํ˜•์ž…๋‹ˆ๋‹ค.

rune String ๋ชจํ˜ธํ•˜๋ฏ€๋กœ ๋ฌธ๋งฅ ํ‚ค์›Œ๋“œ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์˜ ํ™•์‹คํ•œ ์ด์ ์€ ์—†์Šต๋‹ˆ๋‹ค.

BTW: ์ด๊ฒƒ์ด ๋ฐ”๋กœ String string ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค ๐Ÿ˜„

BTW: ์ด๊ฒƒ์ด String string ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค.

์‚ฌ๋žŒ๋“ค์ด ์–ธ์–ด ํ‚ค์›Œ๋“œ๋ฅผ ์›ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” 99%์˜ ์ด์œ ์ž…๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ 1%๋Š” "๋” ์ข‹์•„ ๋ณด์ธ๋‹ค"๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค ๐Ÿ˜

"rune" ํ‚ค์›Œ๋“œ์— ๋Œ€ํ•œ ๊ฐ•ํ•œ ์‹ซ์–ด์š”์— ๋Œ€ํ•ด ์—„์ง€์†๊ฐ€๋ฝ์„ ์•„๋ž˜๋กœ ๋‚ด๋ฆฌ์‹ญ์‹œ์˜ค.

๋” ๋‚˜์€ ๋‹จ์–ด๋Š” ๊ธ€๋ฆฌํ”„์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ์—์„œ ์›์†Œ ๊ธฐํ˜ธ์˜ ์ผ๋ฐ˜์ ์ธ ๊ฐœ๋…์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋ฃฌ์€ ์•„์ด๋Ÿฌ๋‹ˆํ•˜๊ฒŒ๋„ ์œ ๋‹ˆ์ฝ”๋“œ๋กœ ์ •์˜๋œ ํŠน์ • ์œ ํ˜•์˜ ๊ธ€๋ฆฌํ”„์ž…๋‹ˆ๋‹ค. Go๋ฅผ ์„ ํ–‰ ๊ธฐ์ˆ ๋กœ ์–ธ๊ธ‰ํ•˜๋Š” ๊ฒƒ์€ ๋‹ค์†Œ ์šฐ์Šค๊ฝ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ๋ฃฌ์— ๋Œ€ํ•œ ์„ ํ–‰ ๊ธฐ์ˆ ์€ ์„œ๊ธฐ 150๋…„์— ์ž‘์„ฑ๋œ ์‹ค์ œ ๋ฌผ๋ฆฌ์  ๋ฃฌ ์Šคํ†ค์ž…๋‹ˆ๋‹ค. ๋ ˆ๋“œ๋ชฌ๋“œ์˜ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ๋ฃฌ์ด ์•„๋‹™๋‹ˆ๋‹ค. .NET์—๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์ž˜ ์„ค๊ณ„๋œ API ํ‘œ๋ฉด์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด์™€ ๊ฐ™์ด ๊ธฐ์กด ๊ฐœ๋…์„ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒƒ์€ ๋“œ๋ฌธ ์ผ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋งค์šฐ ์—ด์•…ํ•œ API ์ด๋ฆ„ ์ง€์ •์˜ ๋“œ๋ฌธ ์˜ˆ์™ธ์ด๋ฉฐ ๋ถˆ๋งŒ์„ ํ‘œ๋ช…ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๋” ๋‚˜์€ ๋‹จ์–ด๋Š” ๊ธ€๋ฆฌํ”„์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ์—์„œ ์›์†Œ ๊ธฐํ˜ธ์˜ ์ผ๋ฐ˜์ ์ธ ๊ฐœ๋…์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” "Glyph"๊ฐ€ ์œ ๋‹ˆ์ฝ”๋“œ๋ฅผ ๋ณด์ด๋Š” ํ…์ŠคํŠธ๋กœ ๋ Œ๋”๋งํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ์šฉ์–ด์ž…๋‹ˆ๋‹ค(์ถœ์ฒ˜: utf8everywhere.org ).

๊ธ€๋ฆฌํ”„

๊ธ€๊ผด ๋‚ด์˜ ํŠน์ • ๋ชจ์–‘์ž…๋‹ˆ๋‹ค. ๊ธ€๊ผด์€ ์œ ํ˜• ๋””์ž์ด๋„ˆ๊ฐ€ ๋””์ž์ธํ•œ ๊ธ€๋ฆฌํ”„ ๋ชจ์Œ์ž…๋‹ˆ๋‹ค. ์ผ๋ จ์˜ ์ฝ”๋“œ ํฌ์ธํŠธ๋ฅผ ์ง€์ •๋œ ๊ธ€๊ผด ๋‚ด์—์„œ ์ผ๋ จ์˜ ๊ธ€๋ฆฌํ”„๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์€ ํ…์ŠคํŠธ ์…ฐ์ดํ•‘ ๋ฐ ๋ Œ๋”๋ง ์—”์ง„์˜ ์ฑ…์ž„์ž…๋‹ˆ๋‹ค. ์ด ๋ณ€ํ™˜์— ๋Œ€ํ•œ ๊ทœ์น™์€ ๋ณต์žกํ•˜๊ณ  ๋กœ์ผ€์ผ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๋ฉฐ ์œ ๋‹ˆ์ฝ”๋“œ ํ‘œ์ค€์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚ฉ๋‹ˆ๋‹ค.

Go๋ฅผ ์„ ํ–‰ ๊ธฐ์ˆ ๋กœ ์–ธ๊ธ‰ํ•˜๋Š” ๊ฒƒ์€ ๋‹ค์†Œ ์šฐ์Šค๊ฝ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

Utf-8์„ ์ƒ์„ฑํ•  ๋•Œ Rob Pike ๋ฐ Ken Thompson์ด๋ผ๋Š” ์šฉ์–ด ์‚ฌ์šฉ https://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt

Rob Pike๋Š” ํ˜„์žฌ Go์—์„œ ์ž‘์—…ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์›๋ž˜ ์šฉ์–ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋ฃฌ์€ ์•„์ด๋Ÿฌ๋‹ˆํ•˜๊ฒŒ๋„ ์œ ๋‹ˆ์ฝ”๋“œ๋กœ ์ •์˜๋œ ํŠน์ • ์œ ํ˜•์˜ ๊ธ€๋ฆฌํ”„์ž…๋‹ˆ๋‹ค.

๋ฃฌ ๋ฌธ์ž๋Š” ์œ ๋‹ˆ์ฝ”๋“œ๋กœ ์ •์˜๋˜์ง€๋งŒ ๋ฃฌ ๋ฌธ์ž๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ฃฌ ๋ฌธ์ž๋Š” ์œ ๋‹ˆ์ฝ”๋“œ๋กœ ์ •์˜๋˜์ง€๋งŒ ๋ฃฌ ๋ฌธ์ž๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด ์ •ํ™•ํ•œ ์ง„์ˆ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ตœ์‹  ์œ ๋‹ˆ์ฝ”๋“œ ์‚ฌ์–‘(http://www.unicode.org/versions/Unicode11.0.0/UnicodeStandard-11.0.pdf)์—๋Š” "rune"์— ๋Œ€ํ•œ 37๊ฐœ์˜ ์กฐํšŒ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(36๊ฐœ๋งŒ ์œ ํšจํ•ฉ๋‹ˆ๋‹ค. , ๋งˆ์ง€๋ง‰์€ ๋” ํฐ ๋‹จ์–ด์˜ ์ผ๋ถ€์ด๋ฉฐ ํ•ญ์ƒ ๋ฃฌ ๋ฌธ์ž์˜ ๊ฐœ๋ณ„ ๋ฌธ์ž๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด ์ •ํ™•ํ•œ ์ง„์ˆ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ตœ์‹  ์œ ๋‹ˆ์ฝ”๋“œ ์‚ฌ์–‘์—๋Š” "rune"์— ๋Œ€ํ•œ 37๊ฐœ์˜ ํžˆํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋™๊ธฐ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๋ณธ๋ฌธ์—์„œ; ๋ฌธ์ž ์ด๋ฆ„์ด๋‚˜ ํ…์ŠคํŠธ ๋ธ”๋ก ์ด๋ฆ„์— ์—†์Œ(๋ฃฌ ๋ฌธ์ž ๋ฐ ๋ฃฌ ๋ฌธ์ž)

๋™๊ธฐ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๋ณธ๋ฌธ์—์„œ; ๋ฌธ์ž ์ด๋ฆ„์ด๋‚˜ ํ…์ŠคํŠธ ๋ธ”๋ก ์ด๋ฆ„์— ์—†์Œ(๋ฃฌ ๋ฌธ์ž ๋ฐ ๋ฃฌ ๋ฌธ์ž)

์ข‹์•„, ๊ณต์ •ํ•ด. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ํ˜„์žฌ ์œ ๋‹ˆ์ฝ”๋“œ ์‚ฌ์–‘์ด "๋ฃฌ"์ด๋ผ๋Š” ์šฉ์–ด๋ฅผ ์ •์˜ํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ "๋ฃฌ ๋ฌธ์ž"๋ฅผ ์„ค๋ช…ํ•˜๋Š” ์ •๋ณด ํ…์ŠคํŠธ๋ฅผ ์œ„ํ•œ ๋ฌธ์ œ๋กœ ๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค.

๊ณต์‹์ ์œผ๋กœ ์ •์˜ํ•˜๊ณ  ์‚ฌ๋ฌผ์„ ์„ค๋ช…ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ "์ฝ”๋“œ ํฌ์ธํŠธ"์™€ "์ฝ”๋“œ ๋‹จ์œ„"์ž…๋‹ˆ๋‹ค.

  • ์—ญ์‚ฌ์ ์œผ๋กœ ์›๋ž˜ ์ œ์ž‘์ž๋Š” "๋ฃฌ"์ด๋ผ๋Š” ์šฉ์–ด๋ฅผ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ ๊ณต์‹ ์‚ฌ์–‘์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

์งง์„ ํ•„์š”๊ฐ€ ์žˆ๊ฑฐ๋‚˜ ์‚ฌ์šฉ๋ฒ•์ด ์ถ”์•…ํ•ด์ง‘๋‹ˆ๋‹ค.

int CountCommas(string str)
{
    int i = 0;
    foreach(UnicodeCodePoint c in str.AsUnicodeCodePoints())
    {
        if (c == ',') i++;
    }
}

string Trim(string str)
{
    int end = str.Length - 1;
    int start = 0;

    for (start = 0; start < Length; start++)
    {
        if (!UnicodeCodePoint.IsWhiteSpace(str.GetUnicodeCodePointAt(start)))
        {
            break;
        }
    }

    for (end = Length - 1; end >= start; end--)
    {
        if (!UnicodeCodePoint.IsWhiteSpace(str.GetUnicodeCodePointAt(start)))
        {
            break;
        }
    }

    return str.SubString(start, end);
}

๋Œ€

int CountCommas(string str)
{
    int i = 0;
    foreach(Rune c in str.AsRunes())
    {
        if (c == ',') i++;
    }
}

string Trim(string str)
{
    int end = str.Length - 1;
    int start = 0;

    for (start = 0; start < Length; start++)
    {
        if (!Rune.IsWhiteSpace(str.GetRuneAt(start)))
        {
            break;
        }
    }

    for (end = Length - 1; end >= start; end--)
    {
        if (!Rune.IsWhiteSpace(str.GetRuneAt(start)))
        {
            break;
        }
    }

    return str.SubString(start, end);
}

๊ธธ์ด๊ฐ€ ๊ธธ์–ด์ง€๋ฉด CodePoint.IsWhiteSpace ๋ฐ str.GetCodePointAt ๋กœ ๊ฐˆ ๊ฒƒ์ด์ง€๋งŒ Rune ๋„ ์žฌ๋ฏธ์žˆ๊ณ  ์ƒ๊ด€ ์—†์Šต๋‹ˆ๋‹ค.

@jnm2 ๋ฌธ์ž์—ด์— ๊ด€ํ•ด์„œ๋Š” GetCodePointAt ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋„ˆ๋ฌด ๋ชจํ˜ธํ•ฉ๋‹ˆ๋‹ค. char ๊ฐ€ ํ•ด๋‹น ์ธ๋ฑ์Šค์— ์žˆ๊ธฐ๋ฅผ ์›ํ•˜๋Š”์ง€ ์—ฌ๋ถ€(๋ชจ๋“  char s - ์ง์„ ์ด๋ฃจ์ง€ ์•Š์€ ๋Œ€๋ฆฌ์ž๋„ ์œ ํšจํ•œ ์ฝ”๋“œ ํฌ์ธํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์—) ๋˜๋Š” ์Šค์นผ๋ผ / ํ•ด๋‹น ์ธ๋ฑ์Šค์—์„œ ๋ฐœ์ƒํ•œ ๋ฃฌ.

@GrabYourPitchforks GetRuneAt ๊ฐ€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ๋‘˜ ๋‹ค ์˜๋ฏธ๊ฐ€ ์—†๋‹ค๊ณ  ๋ง์”€ํ•˜์‹ญ๋‹ˆ๊นŒ?

@jnm2 ์ €๋Š” ์ด ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ํŠนํžˆ CodePoint ๊ฐ€ ๋„ˆ๋ฌด ๋ชจํ˜ธํ•˜๋‹ค๊ณ  ๋งํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ฉ”์†Œ๋“œ ์ด๋ฆ„ GetXyzAt ์€ ๊ฒฐ๊ตญ ๋“ค์–ด๊ฐ€๋Š” ์œ ํ˜• ์ด๋ฆ„ Xyz ์™€ ์ผ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ ์ด์ œ ํ•ต์‹ฌ ๊ตฌํ˜„์ด ์ฒดํฌ์ธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(https://github.com/dotnet/coreclr/pull/20935 ์ฐธ์กฐ). corefx์— ์ „ํŒŒํ•  ์‹œ๊ฐ„์„ ์ฃผ๋ฉด https://github.com/dotnet/corefx/pull/33395๋ฅผ ํ†ตํ•ด ref API๊ฐ€ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ์—ด์–ด ๋‘๊ฑฐ๋‚˜ ์ ์ ˆํ•˜๋‹ค๊ณ  ์ƒ๊ฐ๋˜๋Š” ๋Œ€๋กœ ํ•ด๊ฒฐํ•˜์‹ญ์‹œ์˜ค.

๋‚˜๋Š” ๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ฑฐ๋‚˜ ๊ธฐ๋ก์„ ์œ„ํ•ด ๋ฌด์—‡์ด๋“  ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋” ๋‚˜์€ ๋‹จ์–ด๋Š” ๊ธ€๋ฆฌํ”„์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ์—์„œ ์›์†Œ ๊ธฐํ˜ธ์˜ ์ผ๋ฐ˜์ ์ธ ๊ฐœ๋…์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” "Glyph"๊ฐ€ ์œ ๋‹ˆ์ฝ”๋“œ๋ฅผ ๋ณด์ด๋Š” ํ…์ŠคํŠธ๋กœ ๋ Œ๋”๋งํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ์šฉ์–ด์ž…๋‹ˆ๋‹ค(์ถœ์ฒ˜: utf8everywhere.org ).

"๋ฃฌ"์€ ์œ ๋‹ˆ์ฝ”๋“œ๋‚˜ ํŠธ๋žœ์ง€์Šคํ„ฐ, ๋งˆ์ดํฌ๋กœ์†Œํ”„ํŠธ, ์˜คํ”ˆ ์†Œ์Šค๊ฐ€ ์กด์žฌํ•˜๊ธฐ ํ›จ์”ฌ ์ด์ „๋ถ€ํ„ฐ ์—ญ์‚ฌ๋ฅผ ํ†ตํ‹€์–ด ์ฒœ ๋…„์ด ๋„˜๋Š” ๊ธฐ๊ฐ„ ๋™์•ˆ ์‚ฌ์šฉ๋œ ์šฉ์–ด์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ ์ถ”๋ก ์€ ๋ฃฌ๋„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ ์–ด๋„ ๊ทธ๊ฒƒ์€ ๋ถ„๋ช…ํžˆ ์ผ๊ด€์„ฑ์ด ์—†๋Š” ๋‹ค๋ฅธ ์ œ์•ˆ์— ๋‹ค๋ฅธ ํ‘œ์ค€์„ ์ž„์˜๋กœ ์ ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ์žˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์•„๋งˆ๋„ ๊ฐ€์žฅ ์ผ๊ด€๋œ ์ฃผ์žฅ๋ณด๋‹ค๋Š” ๋ˆ„๊ฐ€ ๋จผ์ €์˜€๊ฑฐ๋‚˜ ๊ฐ€์žฅ ํฐ ์†Œ๋ฆฌ๋ฅผ ๋ƒˆ๋Š”์ง€์— ๊ด€ํ•œ ๊ฒƒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ œ๊ฐ€ ๋ฌด์—‡์„ ์••๋‹ˆ๊นŒ? ๋‚˜๋Š” ๊ทธ ๊ณผ์ •์„ ์ดํ•ดํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๋Š” ๋Šฆ์—ˆ์ง€๋งŒ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Go๋ฅผ ์„ ํ–‰ ๊ธฐ์ˆ ๋กœ ์–ธ๊ธ‰ํ•˜๋Š” ๊ฒƒ์€ ๋‹ค์†Œ ์šฐ์Šค๊ฝ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

Utf-8์„ ์ƒ์„ฑํ•  ๋•Œ Rob Pike ๋ฐ Ken Thompson์ด๋ผ๋Š” ์šฉ์–ด ์‚ฌ์šฉ https://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt

Rob Pike๋Š” ํ˜„์žฌ Go์—์„œ ์ž‘์—…ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์›๋ž˜ ์šฉ์–ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Go์™€ Rob Pike๋Š” ์ด ์ฃผ์ œ์— ๋Œ€ํ•ด ์ƒ๋Œ€์ ์œผ๋กœ ์ƒˆ๋กœ์šด ์‚ฌ๋žŒ์ž…๋‹ˆ๋‹ค. ์‚ฌ์‹ค ๊ทธ๋“ค์˜ ์˜๊ฒฌ์€ ์—ญ์‚ฌ์ ์œผ๋กœ๋‚˜ ๋Œ€์ค‘ ๋ฌธํ•™๊ณผ ์‚ฌํšŒ์—์„œ ๋ฃฌ์ด ๋ฌด์—‡์ธ์ง€ ์ •์˜ํ•œ๋‹ค๋Š” ์ ์—์„œ ๋‹ค์†Œ ๋ถ€์ ์ ˆํ•ฉ๋‹ˆ๋‹ค. Rob์€ ์†์œผ๋กœ ๋ฃฌ ์Šคํ†ค์„ ๋ง์น˜๋กœ ๋‘๋“œ๋ฆฌ์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ๋ฃฌ์ด ๋ฌด์—‡์ธ์ง€ ์ •์˜ํ•  ์ž๊ฒฉ์ด ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฐ€ ๋ฃฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ง์ ‘ ์“ฐ๊ฑฐ๋‚˜ ์ฝ์„ ์ˆ˜๋„ ์—†์ง€๋งŒ ๋‚ด ์ถ”์ธก์ž…๋‹ˆ๋‹ค. ๊ธฐ๊ปํ•ด์•ผ ๊ทธ๋Š” ์ธ์ฝ”๋”ฉ์„ ํ†ตํ•ด ๊ทธ ๊ฐœ๋…์„ ํฌ์ฐฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ•œ์ž, ์•„๋ž์–ด ๋ฌธ์ž ๋˜๋Š” ํ•œ๊ธ€ ๋˜๋Š” ์›ƒ๋Š” ์–ผ๊ตด์ด ๋ฃฌ์ด๊ฑฐ๋‚˜ "์ฝ”๋“œ ํฌ์ธํŠธ"์ธ ๋‹ค๋ฅธ ๋ชจ๋“  ๊ฒƒ์ด ์ด์ œ ๋ฃฌ์ด๋ผ๊ณ ๋„ ๋งํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ๊ทธ๋Ÿฐ ๊ฒƒ. ์ด ์šฉ์–ด๋ฅผ ๊ฑฐ์˜ ๋ฌด๋ก€ํ•˜๊ฒŒ ์ง“๋ฐŸ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋ชจ๋“  ๊ฒƒ์ด ๋ฃฌ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋ฃฌ์€ ํ…์ŠคํŠธ ์ธ์ฝ”๋”ฉ ์˜์—ญ์—์„œ ๋‚œํ•ดํ•œ ๊ฒƒ์„ ๋‚˜ํƒ€๋‚ด๋Š” 4๊ธ€์ž ์™€์ผ๋“œ์นด๋“œ ์šฉ์–ด์— ๋ถˆ๊ณผํ•ฉ๋‹ˆ๋‹ค.

๋ฃฌ์€ ์•„์ด๋Ÿฌ๋‹ˆํ•˜๊ฒŒ๋„ ์œ ๋‹ˆ์ฝ”๋“œ๋กœ ์ •์˜๋œ ํŠน์ • ์œ ํ˜•์˜ ๊ธ€๋ฆฌํ”„์ž…๋‹ˆ๋‹ค.

๋ฃฌ ๋ฌธ์ž๋Š” ์œ ๋‹ˆ์ฝ”๋“œ๋กœ ์ •์˜๋˜์ง€๋งŒ ๋ฃฌ ๋ฌธ์ž๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์œ ๋‹ˆ์ฝ”๋“œ๋Š” ๋ฃฌ์ด๋‚˜ ๋ฃฌ์ด ๋ฌด์—‡์ธ์ง€ ์žฌ์ •์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋“ค์ด ๊ทธ๋ ‡๊ฒŒ ํ•œ๋‹ค๋ฉด, ๊ทธ๋“ค์€ ๊ทธ๋“ค์˜ ์ž„๋ฌด๋ฅผ ์ดˆ๊ณผํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ๋Œ€์ค‘์—๊ฒŒ ๋ฃฌ์ด ๋ฌด์—‡์ธ์ง€ ๋งํ•  ์ผ์ด ์—†์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค ๊ทธ๋“ค์€ ์ƒˆ๋กœ์šด ์–ธ์–ด๋‚˜ ๋ฌธ์ž ์ฒด๊ณ„๋ฅผ ์ •์˜ํ•˜๋Š” ์‚ฌ์—…์ด ์ „ํ˜€ ์—†์Šต๋‹ˆ๋‹ค. ์ฒœ ๋…„์ด ์ง€๋‚œ ์ง€๊ธˆ ๋ถ„๋ช…ํžˆ ๊ณผ์ค‘ํ•œ ์šฉ์–ด๊ฐ€ ๋œ ๋‹จ์–ด๋ฅผ ์ฐจ์šฉํ•˜๊ณ  ์ƒˆ๋กœ์šด ๊ฐœ๋…์„ ์ƒ๊ฐํ•ด๋‚ธ ๊ฒƒ์ฒ˜๋Ÿผ ํ™˜ํ˜ธ์„ฑ์„ ์ง€๋ฅด๊ธฐ๋งŒ ํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋ฃฌ ๋ฌธ์ž๋Š” ๋ฃฌ๋งŒ์œผ๋กœ ๊ตฌ์„ฑ๋˜๋ฉฐ, ๋ฃฌ์€ ์ด๋ฏธ ํ™•๋ฆฝ๋œ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. ๊ธธ๊ฑฐ๋ฆฌ์—์„œ ์•„๋ฌด์—๊ฒŒ๋‚˜ ๋ฃฌ์ด ๋ฌด์—‡์ธ์ง€ ๋ฌป๋Š”๋‹ค๋ฉด ๊ทธ๋“ค์€ ์œ ๋‹ˆ์ฝ”๋“œ๋ฅผ ์ƒ๊ฐํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์œ„์˜ ๋ชจ๋“  ๋ฌธ์ œ ์™ธ์—๋„ ๋ฃฌ์€ ์ตœ์•…์˜ ๋ถ€๋ถ„์ธ ๋นˆ์•ฝํ•œ ์€์œ ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์•„๋ฌด๊ฒƒ๋„ ๋ช…ํ™•ํžˆํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋˜ ๋‹ค๋ฅธ ์ˆ˜์ค€์˜ ํ˜ผ๋ž€์„ ๋”ํ•  ๋ฟ์ž…๋‹ˆ๋‹ค. ์ด ์ฃผ์ œ๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ์‚ฌ๋žŒ์ด๋ผ๋ฉด ๋ˆ„๊ตฌ๋‚˜ ๋ฃฌ์ด ํŠน์ • ๋ฌธํ™”๊ถŒ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์—ญ์‚ฌ์  ์“ฐ๊ธฐ ์ฒด๊ณ„๋ผ๋Š” ๋งฅ๋ฝ์„ ์ดํ•ดํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ช…ํ™•ํ•œ ์„ค๋ช…๊ณผ ์ฝ๊ธฐ๋ฅผ ๊ฑฐ์ณ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์„ค๋ช…์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ง„ํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. "๋ฃฌ์€ ์œ ๋‹ˆ์ฝ”๋“œ ์ฝ”๋“œ ํฌ์ธํŠธ์ž…๋‹ˆ๋‹ค." "ํ•˜์ง€๋งŒ ์™œ ๊ทธ๊ฒƒ์„ ์ฝ”๋“œ ํฌ์ธํŠธ๋ผ๊ณ  ๋ถ€๋ฅด์ง€ ์•Š์Šต๋‹ˆ๊นŒ?" "๊ธ€์Ž„, ๋„ˆ๋ฌด ๊ธธ๊ธฐ ๋•Œ๋ฌธ์—."๋˜๋Š” "๋ˆ„๊ตฐ๊ฐ€ ๋ฃฌ์„ ์ข‹์•„ํ•œ๋‹ค๊ณ  ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค." ๊ทธ๋ž˜์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ˆ„๊ตฐ๊ฐ€๋Š” 9๊ธ€์ž๊ฐ€ 4๊ธ€์ž์— ๋น„ํ•ด ๋„ˆ๋ฌด ๋งŽ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์—(์ธํ…”๋ฆฌ์„ผ์Šค๋กœ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ์ด ์žˆ๊ณ  Java Kingdom Of Nouns์— ๋น„ํ•˜๋ฉด ์•„๋ฌด๊ฒƒ๋„ ์•„๋‹˜์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ ) ์ด์ œ ์šฐ๋ฆฌ๋Š” ์ด ํ˜ผ๋ž€์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์ด๊ฒƒ์„ ์ˆ˜์ฒœ ๋ช…์—๊ฒŒ ์„ค๋ช…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์œ ๋‹ˆ์ฝ”๋“œ์— ์†์„ ๋Œ€์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ์—์„œ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ using ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์šฉ์–ด๋ฅผ ์ค„์ด์‹ญ์‹œ์˜ค.

UnicodeCodePoint์ผ ํ•„์š”๋„ ์—†์œผ๋ฉฐ ๋‹จ์ˆœํžˆ CodePoint์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ด๋ฏธ ๋…ํŠนํ•ฉ๋‹ˆ๋‹ค. "CodePoint"๋ณด๋‹ค ๊ธด API ์šฉ์–ด๊ฐ€ ๋งŽ์ด ์žˆ์œผ๋ฏ€๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜๋„ ๋„ˆ๋ฌด ๊ธธ๋‹ค๋ฉด ์•ฝ๊ฐ„์˜ ์•ฝ์–ด๊ฐ€ ์žˆ๋Š” using ๋ฌธ์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

๋‚˜๋Š” ์ด๊ฒƒ์ด ์‹ค์ œ๋กœ ๋งŽ์€ ๊ฐ€์น˜๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์œ ์šฉํ•œ ๊ฒƒ์—์„œ ๋…ผ๋ฆฌ์  ๊ทผ๊ฑฐ๋ฅผ ๊ฐ–์ง€ ์•Š๋Š” ์žก๋‹คํ•œ ์ธํ„ฐ๋ทฐ ์งˆ๋ฌธ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ ์–ด๋„ "์ด์ •ํ‘œ"๋ผ๋Š” ์€์œ ์˜ ๊ฒฝ์šฐ ๋Œ๊ณผ ์•”์„์—์„œ ํŒŒ์ƒ๋œ ๊ฐœ๋…์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ์— ์‚ฌ์šฉ๋˜๋Š” ์ƒ์ง•์  ๋‹จ์–ด์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์ง€๋งŒ ์ด์ •ํ‘œ๋Š” ์‹ค์ œ ์„ค๋ช…์ ์ธ ์˜๋ฏธ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. ๋ชจ๋‘์—๊ฒŒ ์นœ์ˆ™ํ•œ ๊ฐœ๋…์„ ์ฆ‰์‹œ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์•„ํ•˜, ๋งˆ์น˜ ๊ธด ์—ฌํ–‰์„ ํ•˜๊ณ  ์˜ค์†”๊ธธ์„ ์ง€๋‚˜๊ฐˆ ๋•Œ์™€ ๊ฐ™์€ ์ด์ •ํ‘œ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๋ฌด์–ธ๊ฐ€๋ฅผ ์‹œ๊ฐํ™”ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๊ณ  ์ฆ‰์‹œ ๊ด€๋ฆฌ ์–ธ์–ด๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š” ๋ฉ‹์ง„ ์‹ค์„ธ๊ณ„ ์€์œ ์ž…๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ์ด ์ฃผ์ œ์— ๋Œ€ํ•ด ์ž˜ ์•Œ์ง€ ๋ชปํ•œ๋‹ค๋ฉด ๋ฃฌ์— ๋Œ€ํ•ด ์ด๋Ÿฐ ์‹์œผ๋กœ ์ด์•ผ๊ธฐํ•˜๋Š” ๊ฒƒ์„ ์ƒ์ƒํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด ์‹œ์ ์—์„œ ๊ทธ๋“ค์€ ์ด๋ฏธ ๊ทธ๊ฒƒ์ด ์ฝ”๋“œ ํฌ์ธํŠธ์— ๋Œ€ํ•œ ์†์ž„์ˆ˜ ์šฉ์–ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋” ๋‚˜์€ ๋‹จ์–ด๋Š” ๊ธ€๋ฆฌํ”„์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ์—์„œ ์›์†Œ ๊ธฐํ˜ธ์˜ ์ผ๋ฐ˜์ ์ธ ๊ฐœ๋…์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” "Glyph"๊ฐ€ ์œ ๋‹ˆ์ฝ”๋“œ๋ฅผ ๋ณด์ด๋Š” ํ…์ŠคํŠธ๋กœ ๋ Œ๋”๋งํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ์šฉ์–ด์ž…๋‹ˆ๋‹ค(์ถœ์ฒ˜: utf8everywhere.org).

"๋ฃฌ"์€ ์œ ๋‹ˆ์ฝ”๋“œ๋‚˜ ํŠธ๋žœ์ง€์Šคํ„ฐ, ๋งˆ์ดํฌ๋กœ์†Œํ”„ํŠธ, ์˜คํ”ˆ ์†Œ์Šค๊ฐ€ ์กด์žฌํ•˜๊ธฐ ํ›จ์”ฌ ์ด์ „๋ถ€ํ„ฐ ์—ญ์‚ฌ๋ฅผ ํ†ตํ‹€์–ด ์ฒœ ๋…„์ด ๋„˜๋Š” ๊ธฐ๊ฐ„ ๋™์•ˆ ์‚ฌ์šฉ๋œ ์šฉ์–ด์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ ์ถ”๋ก ์€ ๋ฃฌ๋„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚ด ์š”์ ์€ "๊ธ€๋ฆฌํ”„"๋ผ๋Š” ๋‹จ์–ด๊ฐ€ ์ด๋ฏธ ํ…์ŠคํŠธ ๋ Œ๋”๋ง์˜ ๊ฐœ๋… ์ค‘ ํ•˜๋‚˜๋กœ ์‚ฌ์šฉ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŠน์ • ๊ธ€๊ผด์—์„œ ํ•ด๋‹น ๋ฌธ์ž์˜ ๊ทธ๋ž˜ํ”ฝ ํ‘œํ˜„์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์บ๋ฆญํ„ฐ๋Š” ๋‹ค์–‘ํ•œ ๊ธ€๋ฆฌํ”„๋กœ ํ‘œํ˜„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

...๋˜ 10,000๋ฏธํ„ฐ ๋ทฐ์˜ @benaadams ์™€ ์ •๋‹ต๊ณผ ํ•จ๊ป˜ ๐Ÿ˜

์†”์งํžˆ ๋งํ•ด์„œ ์šฐ๋ฆฌ๋Š” ์˜› ๊ฒฉ์–ธ์„ ๋”ฐ๋ผ ์‚ด์•„์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. "์ผ๋ถ€ ์‚ฌ๋žŒ๋“ค์„ ํ•ญ์ƒ ํ–‰๋ณตํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๊ณ  ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์„ ํ•œ๋™์•ˆ ํ–‰๋ณตํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์„ ํ•ญ์ƒ ํ–‰๋ณตํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์‹œ๊ฐ„." ์ด๊ฒƒ์€ ๋งค์šฐ ์ „์ž์˜ ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค.

์‹œ์งˆ?

Exit, pursued by a bear.

์ด API๋ฅผ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ์œผ๋กœ์„œ ์ €๋Š” ์ฝ”๋“œ ํฌ์ธํŠธ์— ๊ฐ•๋ ฅํ•˜๊ฒŒ ํ•œ ํ‘œ๋ฅผ ๋˜์ง‘๋‹ˆ๋‹ค. ์œ ๋‹ˆ์ฝ”๋“œ ์šฉ์–ด๋Š” ์ด๋ฏธ ์ถฉ๋ถ„ํžˆ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ณ  ๋ถˆ์ผ์น˜๊ฐ€ ์ด๋ฏธ ๋งŽ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ณณ์—์„œ "์ฝ”๋“œ ํฌ์ธํŠธ"๋ผ๊ณ  ๋งํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋‚ด ์‚ถ์ด ํ›จ์”ฌ ์‰ฌ์›Œ์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ง€๊ธˆ ์นจ๋Œ€์— ๋ˆ„์›Œ์žˆ๋‹ค. ์˜†์œผ๋กœ ๋Œ์•„์„œ๋ฉด ๋ฒฝ์— ๊ธฐ๋Œ€์–ด ์žˆ๋Š” ํ™”์ดํŠธ๋ณด๋“œ์™€ ๋งˆ์ฃผํ•˜๊ฒŒ ๋œ๋‹ค. ๋‚ด๊ฐ€ C#์—์„œ IDN์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋‚ด๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๋Š” ๋™์•ˆ ๋ช‡ ๋‹ฌ ๋™์•ˆ ๊ทธ ํ™”์ดํŠธ๋ณด๋“œ๋Š” ๋‹ค์–‘ํ•œ ๋‚™์„œ์™€ ์ฐจํŠธ์˜ ๊ณ ํ–ฅ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ง€์˜ฅ ๊นŠ์€ ๊ณณ์—์„œ ๋ถˆ๋Ÿฌ์˜จ ์œ ๋ฌผ์ฒ˜๋Ÿผ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ์„ค๋ช…ํ•˜๋Š” ๋…ผ๋ฆฌ๋ฅผ ์„ค๋ช…ํ•˜๋ ค๊ณ  ์‹œ๋„ํ–ˆ๋‹ค๋ฉด, ๋‚˜๋Š” ํ•  ์ˆ˜ ์—†์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ œ ์‚ถ์„ ํž˜๋“ค๊ฒŒ ํ•˜์ง€ ๋ง์•„์ฃผ์„ธ์š”. ์ฝ”๋“œ ํฌ์ธํŠธ๋Š” ์ฝ”๋“œ ํฌ์ธํŠธ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋ฃฌ ๋ฌธ์ž, ๋ฌธ์ž, ๋ฌธ์ž, ๋ฌธ์ž ๋˜๋Š” ๊ธฐํ˜ธ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ธ๊ฐ„์—๊ฒŒ ์˜๋ฏธ ์žˆ๋Š” ๊ฒƒ์„ ๋‚˜ํƒ€๋‚ผ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ œ์–ด ์ฝ”๋“œ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. "๋ฃฌ"์ด๋ผ๋Š” ์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ์‹œ๊ฐ์  ๊ธฐํ˜ธ๋ฅผ ๋‚˜ํƒ€๋‚ด์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋‹จ์ง€ ์ฝ”๋“œ ํฌ์ธํŠธ์ž…๋‹ˆ๋‹ค.

์ข€ ๋” ๊ตฌ์ฒด์ ์ธ ์ฃผ์žฅ์€ "๋ฃฌ"์ด ๋‹จ์ผ ์ž์†Œ์˜ ํ‘œํ˜„์„ ์˜๋ฏธํ•œ๋‹ค๋Š” ๊ฒƒ์ธ๋ฐ, ์ด๋Š” ์ข…์ข… ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ ํฌ์ธํŠธ ์ˆ˜์™€ ์ž์†Œ ์ˆ˜๋ฅผ ์„ธ์–ด ๋ณด๋ฉด ๋‘ ๊ฐœ์˜ ๋งค์šฐ ๋‹ค๋ฅธ ์ˆซ์ž๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋™์ผํ•œ ์ž์†Œ ์‹œํ€€์Šค๋Š” ๋‘ ๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ์ผ๋ จ์˜ ์ฝ”๋“œ ํฌ์ธํŠธ๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋” ๋‚˜์€ ๋‹จ์–ด๋Š” ๊ธ€๋ฆฌํ”„์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ์—์„œ ์›์†Œ ๊ธฐํ˜ธ์˜ ์ผ๋ฐ˜์ ์ธ ๊ฐœ๋…์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ทธ๊ฒŒ ๋” ๋‚˜์˜๋‹ค. ๋‹จ์ผ ์ฝ”๋“œ ํฌ์ธํŠธ๋Š” ์—ฌ๋Ÿฌ ๊ธ€๋ฆฌํ”„๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๊ณ  ๋‹จ์ผ ๊ธ€๋ฆฌํ”„๋Š” ์—ฌ๋Ÿฌ ์ฝ”๋“œ ํฌ์ธํŠธ๋ฅผ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ ๋งคํ•‘์€ ์‹œ์Šคํ…œ, ํ”„๋กœ๊ทธ๋žจ, ์„œ์ฒด์— ๋”ฐ๋ผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ชจ๋“  ๋‹จ์–ด์—๋Š” ๋งค์šฐ ๊ตฌ์ฒด์ ์ธ ๊ธฐ์ˆ ์  ์˜๋ฏธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ œ์•ˆ์˜ ๋งฅ๋ฝ์—์„œ ์ฐจ์ด์ ์ด ์ค‘์š”ํ•˜์ง€ ์•Š์€ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ๋‹ค๋ฅธ ๊ณณ, ํŠนํžˆ ์˜์–ด ์ด์™ธ์˜ ์–ธ์–ด์—์„œ ์‹ค์งˆ์ ์ธ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

๋…์ผ์–ด์™€ ๊ฐ™์€ ์ผ๋ฐ˜์ ์ธ ์–ธ์–ด์—์„œ๋„ ํ…์ŠคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ์–ด๋ ค์šด์ง€ ๋ณด์—ฌ์ฃผ๋Š” ์˜ˆ:

  1. รŸ ๋ฅผ ๋Œ€๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด SS ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
  2. ๋‹ค์‹œ ์†Œ๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด ss ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ:

  • char.ToUpper('รŸ') ๋Š” ๋ฌด์—‡์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? (ํ•˜๋‚˜์˜ ๋ฌธ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.)
  • ๋‚ด ์ „ํ™”๊ธฐ๊ฐ€ ์ด ํ…์ŠคํŠธ ์ƒ์ž์— ์ž…๋ ฅํ•  ์ˆ˜ ์—†๋Š” รŸ์˜ ๋Œ€๋ฌธ์ž ๋ฒ„์ „์ด ์œ ๋‹ˆ์ฝ”๋“œ 5.1์— ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ถ™์—ฌ๋„ฃ์œผ๋ ค๊ณ  ํ•˜๋ฉด SS๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค. ์ด์ œ ์ƒํ•œ/ํ•˜ํ•œ ๋ณ€ํ™˜์ด ํ›จ์”ฌ ๋” ๋ชจํ˜ธํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฌธ์ž์—ด์˜ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๋ฐ”๊พธ๋ฉด ๊ธธ์ด๊ฐ€ ๋ฐ”๋€๋‹ˆ๋‹ค.
  • ๋Œ€์†Œ๋ฌธ์ž ๋ณ€๊ฒฝ์€ ๋ฉฑ๋“ฑ์„ฑ ๋˜๋Š” ๋˜๋Œ๋ฆด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ๋‹จ์ˆœํžˆ ๊ฐ ๋ฌธ์ž์—ด์„ ์†Œ๋ฌธ์ž๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š๋Š” ๋น„๊ต๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์šฉ์–ด๊ฐ€ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๋Š” ์ƒํ™ฉ์˜ ์ง์ ‘์ ์ธ ์˜ˆ๋Š” ์•„๋‹ˆ์ง€๋งŒ ์šฐ๋ฆฌ๊ฐ€ ์ผ๋ฐ˜์ ์œผ๋กœ ์ƒ๊ฐํ•˜์ง€ ์•Š๋Š” ์ผ์ข…์˜ ๊ทน๋‹จ์  ์ธ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Œ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๊ฐ ์šฉ์–ด์— ๊ณ ์œ ํ•˜๊ณ  ์ผ๊ด€๋œ ์˜๋ฏธ๋ฅผ ๋ถ€์—ฌํ•˜๋ฉด ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ํŒ€์›์—๊ฒŒ ์ž์†Œ ์ˆ˜๋ฅผ ์„ธ๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•ด ๋‹ฌ๋ผ๊ณ  ์š”์ฒญํ•˜๋ฉด ๊ทธ๋“ค์€ ์ •ํ™•ํžˆ ๋ฌด์—‡์„ ๊ณ„์‚ฐํ•˜๊ณ  ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๊ทธ๋“ค์—๊ฒŒ ์ฝ”๋“œ ํฌ์ธํŠธ๋ฅผ ์„ธ๋„๋ก ์š”์ฒญํ•˜๋ฉด, ๊ทธ๋“ค์€ ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋Š”์ง€ ์ •ํ™•ํžˆ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ •์˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์–ธ์–ด ๋ฐ ๊ธฐ์ˆ ๊ณผ ๋ฌด๊ด€ํ•ฉ๋‹ˆ๋‹ค.

JavaScript ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋ฃฌ ์ˆ˜๋ฅผ ์„ธ์–ด ๋‹ฌ๋ผ๊ณ  ํ•˜๋ฉด ๋จธ๋ฆฌ๊ฐ€ ์„ธ ๊ฐœ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์œ„ํ‚คํ”ผ๋””์•„๋Š” ๋งํ•œ๋‹ค

์œ ๋‹ˆ์ฝ”๋“œ๋Š” 0hex์—์„œ 10FFFFhex ๋ฒ”์œ„์˜ 1,114,112 ์ฝ”๋“œ ํฌ์ธํŠธ์˜ ์ฝ”๋“œ ๊ณต๊ฐ„์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

์ฝ”๋“œํฌ์ธํŠธ๊ฐ€ ์ •์‹ ๋ช…์นญ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ฝ์—ˆ์ง€๋งŒ ์ฝ”๋“œ ํฌ์ธํŠธ๊ฐ€ ์ž˜๋ชป๋œ ์ด์œ ์— ๋Œ€ํ•œ ๊ฐ•์ œ ์ธ์ˆ˜๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ฝ”๋“œ ํฌ์ธํŠธ๊ฐ€ ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉํ•˜๊ธฐ์— ์˜ฌ๋ฐ”๋ฅธ ์šฉ์–ด๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์ตœ์†Œํ•œ ์œ ๋‹ˆ์ฝ”๋“œ ํ‘œ์ค€์— ๋”ฐ๋ผ 10FFFF(http://unicode.org/glossary/#code_point) ์ด์ƒ์˜ ๊ฐ’์€ ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ ๋ฌธ์žฅ์ด ์ž˜๋ชป๋œ ๊ฒƒ์€ ์•„๋‹๊นŒ? "์ฝ”๋“œ ๊ณต๊ฐ„์˜ ๋ชจ๋“  ๊ฐ’"์ด๋ผ๊ณ  ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ •์ˆ˜๋ฅผ ์ž˜๋ชป ์ดํ•ดํ•˜๋Š” ๋™์‹œ์— ๋ชจ๋“  ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ "๋ฃฌ"์€ ์œ ๋‹ˆ์ฝ”๋“œ์™€ ์•„๋ฌด ๊ด€๋ จ์ด ์—†๋Š” ํ˜„์‹ค ์„ธ๊ณ„์˜ ์˜๋ฏธ ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋…์ผ์—์„œ "๋ฃฌ"์ด๋ผ๋Š” ๋‹จ์–ด๋Š” ๋‚˜์น˜์˜ ์˜๋ฏธ๋ฅผ ๋‹ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋ฃฌ์€ ๋‚˜์น˜๊ฐ€ ์–ธ๊ธ‰ํ•˜๊ธฐ๋ฅผ ์ข‹์•„ํ–ˆ๋˜ "๊ฒŒ๋ฅด๋งŒ" ์—ญ์‚ฌ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” "๋ฃฌ"์ด ํ˜ผ๋ž€์Šค๋Ÿฌ์šด ์ด๋ฆ„์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ์‚ฌ๋žŒ์ด "๋ฃฌ"์„ ์ •๋ง ์ข‹์•„ ํ•˜๊ฑฐ๋‚˜ ์ •ํ™•์„ฑ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ์ฃผ์žฅ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์ง๊ด€์ ์œผ๋กœ, ๊ทธ๊ฒƒ์€ ์ •๋ง ๋‚˜์œ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

๊ทธ ๋ฌธ์žฅ์ด ์ž˜๋ชป๋œ ๊ฒƒ์€ ์•„๋‹๊นŒ? "์ฝ”๋“œ ๊ณต๊ฐ„์˜ ๋ชจ๋“  ๊ฐ’"์ด๋ผ๊ณ  ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ •์ˆ˜๋ฅผ ์ž˜๋ชป ์ดํ•ดํ•˜๋Š” ๋™์‹œ์— ๋ชจ๋“  ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๊ทธ ๋ฌธ์žฅ์ด ๋งž์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ ๊ณต๊ฐ„์€ U+0000 ~ U+10FFFF์ž…๋‹ˆ๋‹ค. ์œ ๋‹ˆ์ฝ”๋“œ๋Š” ์ด๋ก ์ ์œผ๋กœ ์–ธ์  ๊ฐ€๋Š” ๊ทธ ์ด์ƒ์œผ๋กœ ํ™•์žฅ๋  ์ˆ˜ ์žˆ์ง€๋งŒ UTF-8๊ณผ UTF-16์„ ๊นจ๋œจ๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์ธ์ฝ”๋”ฉ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

ํŽธ์ง‘: ์‚ฌ์‹ค, UTF-16 ํŒŒ์†์— ๋Œ€ํ•ด ์ €๋ฅผ ์ธ์šฉํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ํ•˜์ง€๋งŒ UTF-8์ด ํŒŒ์†๋  ๊ฒƒ์ด๋ผ๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค. UTF-8์€ ํ™•์‹คํžˆ 0xFFFFFF(2^24 -1)๋ฅผ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

ํŽธ์ง‘ 2: ๋ช…ํ™•ํžˆ ํ•˜๊ธฐ ์œ„ํ•ด ์œ ๋‹ˆ์ฝ”๋“œ๋Š” ์ฝ”๋“œ ํฌ์ธํŠธ๊ฐ€ U+10FFFF๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ๋ช…์‹œํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๊ณ  ํ•ด์„œ ํ˜„์žฌ 0x110000๊ฐœ์˜ ์ฝ”๋“œ ํฌ์ธํŠธ๊ฐ€ ์žˆ๋‹ค๋Š” ์˜๋ฏธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์ฝ”๋“œ ํฌ์ธํŠธ๋Š” ํ• ๋‹น๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

@์ œ ๋„ฅ์„œ @GSPP

ํ˜„์žฌ ๋งˆ์Šคํ„ฐ์— ์ฒดํฌ์ธ๋œ ์ด ์œ ํ˜•( System.Text.Rune )์€ "์œ ๋‹ˆ์ฝ”๋“œ ์Šค์นผ๋ผ ๊ฐ’"์— ๋งค์šฐ ๊ตฌ์ฒด์ ์œผ๋กœ ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค( ์šฉ์–ด์ง‘ ์ฐธ์กฐ ). -1 , 0xD800 ๋˜๋Š” 0x110000 ๊ฐ’์—์„œ ๊ตฌ์„ฑํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์œ ํ˜•์˜ ctor๊ฐ€ ์˜ˆ์™ธ๋ฅผ throwํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์œ ๋‹ˆ์ฝ”๋“œ ์‚ฌ์–‘์— ๋”ฐ๋ฅธ ์Šค์นผ๋ผ ๊ฐ’์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. Rune ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฉ”์†Œ๋“œ์— ๋Œ€ํ•œ ์ž…๋ ฅ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์œ ํ˜• ์‹œ์Šคํ…œ์€ ์ด๋ฏธ ์œ ํšจํ•œ ์Šค์นผ๋ผ ๊ฐ’์œผ๋กœ ๊ตฌ์„ฑ๋˜์—ˆ์Œ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์‹œ: ๋Œ€์†Œ๋ฌธ์ž ๋ณ€ํ™˜, .NET Framework์˜ ๋ชจ๋“  ๋Œ€์†Œ๋ฌธ์ž ๋ณ€ํ™˜ API๋Š” _๋‹ฌ๋ฆฌ ์–ธ๊ธ‰๋˜์ง€ ์•Š๋Š” ํ•œ_ ๋‹จ์ˆœ ๋Œ€์†Œ๋ฌธ์ž ์ ‘๊ธฐ๋ผ๋Š” ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์ˆœ ๋Œ€์†Œ๋ฌธ์ž ์ ‘๊ธฐ ๊ทœ์น™์— ๋”ฐ๋ผ ๋ชจ๋“  ์ž…๋ ฅ ์Šค์นผ๋ผ ๊ฐ’์— ๋Œ€ํ•ด ์ถœ๋ ฅ ์†Œ๋ฌธ์ž, ๋Œ€๋ฌธ์ž ๋ฐ ์ œ๋ชฉ ํ˜•์‹๋„ ๊ฐ๊ฐ ์ •ํ™•ํžˆ ํ•˜๋‚˜์˜ ์Šค์นผ๋ผ ๊ฐ’์ด ๋˜๋„๋ก ๋ณด์žฅ๋ฉ๋‹ˆ๋‹ค. (์ˆซ์ž 0-9 ๋˜๋Š” ๊ตฌ๋‘์  ๊ธฐํ˜ธ์™€ ๊ฐ™์€ ์ผ๋ถ€ ์ž…๋ ฅ์€ ๋Œ€์†Œ๋ฌธ์ž ๋ณ€ํ™˜ ๋งต์— ํ•ญ๋ชฉ์ด ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ _ToUpper_์™€ ๊ฐ™์€ ์—ฐ์‚ฐ์€ ๋‹จ์ˆœํžˆ ์ž…๋ ฅ ์Šค์นผ๋ผ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.) ๋˜ํ•œ ๊ฐ„๋‹จํ•œ ๋Œ€์†Œ๋ฌธ์ž ์ ‘๊ธฐ ๊ทœ์น™์— ๋”ฐ๋ผ ์ž…๋ ฅ์ด ๋‹ค์Œ๊ณผ ๊ฐ™์„ ๊ฒฝ์šฐ ๊ธฐ๋ณธ ๋‹ค๊ตญ์–ด ํ‰๋ฉด(BMP)์—์„œ ์ถœ๋ ฅ๋„ BMP์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅ์ด ๋ณด์กฐ ํ‰๋ฉด์— ์žˆ์œผ๋ฉด ์ถœ๋ ฅ๋„ ๋ณด์กฐ ํ‰๋ฉด์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—๋Š” ๋ช‡ ๊ฐ€์ง€ ๊ฒฐ๊ณผ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ์งธ, Rune.ToUpper ๋ฐ ์นœ๊ตฌ๋Š” ํ•ญ์ƒ ๋‹จ์ผ _Rune_(์Šค์นผ๋ผ) ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋‘˜์งธ, String.ToUpper ๋ฐ ์นœ๊ตฌ๋Š” ํ•ญ์ƒ ์ž…๋ ฅ๊ณผ ์ •ํ™•ํžˆ ๋™์ผํ•œ ๊ธธ์ด์˜ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋Œ€์†Œ๋ฌธ์ž ๋ณ€ํ™˜ ์ž‘์—… ํ›„์— 'รŸ'(์†Œํ˜• eszett)๋ฅผ ํฌํ•จํ•˜๋Š” ๋ฌธ์ž์—ด์ด ์‚ฌ์šฉ๋˜๋Š” ๋ฌธํ™”๊ถŒ์— ๋”ฐ๋ผ 'รŸ'(๋ณ€๊ฒฝ ์—†์Œ) ๋˜๋Š” 'แบž'(majuscule eszett)์„ ํฌํ•จํ•˜๊ฒŒ ๋  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ "SS"๋ฅผ ํฌํ•จํ•˜์ง€ _์•Š์Šต๋‹ˆ๋‹ค_. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฌธ์ž์—ด ๊ธธ์ด๊ฐ€ ๋ณ€๊ฒฝ๋˜๊ณ  ๊ณต๊ฐœ์ ์œผ๋กœ ๋…ธ์ถœ๋œ ๊ฑฐ์˜ ๋ชจ๋“  .NET ๋Œ€์†Œ๋ฌธ์ž ๋ณ€ํ™˜ API๊ฐ€ ๊ฐ„๋‹จํ•œ ๋Œ€์†Œ๋ฌธ์ž ์ ‘๊ธฐ ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์…‹์งธ, Utf8String.ToUpper ๋ฐ ์นœ๊ตฌ(์•„์ง ์ฒดํฌ์ธํ•˜์ง€ ์•Š์Œ)๋Š” _Length_ ์†์„ฑ์ด ์ž…๋ ฅ ๊ฐ’์˜ _Length_ ์†์„ฑ๊ณผ ์ผ์น˜ํ•˜๋Š” ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜์ง€ _์•Š์Šต๋‹ˆ๋‹ค_. (๋ฌธ์ž์—ด์˜ UTF-16 ์ฝ”๋“œ ๋‹จ์œ„ ์ˆ˜๋Š” ๊ฐ„๋‹จํ•œ ๋Œ€์†Œ๋ฌธ์ž ์ ‘๊ธฐ ํ›„์— ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์ง€๋งŒ ๋ฌธ์ž์—ด์˜ UTF-8 ์ฝ”๋“œ ๋‹จ์œ„ ์ˆ˜๋Š” ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” BMP ๊ฐ’์ด UTF-16 ๋ฐ UTF-๋กœ ์ธ์ฝ”๋”ฉ๋˜๋Š” ๋ฐฉ์‹ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. 8.)

๋‚ด๋ถ€์ ์œผ๋กœ ๋‹จ์ˆœํ•œ ๋Œ€์†Œ๋ฌธ์ž ์ ‘๊ธฐ ๊ทœ์น™์ด ์•„๋‹Œ ๋ณต์žกํ•œ ๋Œ€์†Œ๋ฌธ์ž ์ ‘๊ธฐ ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜๋Š” ์ผ๋ถ€ .NET API๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. String.Equals , String.IndexOf , String.Contains ๋ฐ ์œ ์‚ฌํ•œ ์ž‘์—…์€ ๋ฌธํ™”์— ๋”ฐ๋ผ ๋ณต์žกํ•œ ๋Œ€์†Œ๋ฌธ์ž ์ ‘๊ธฐ ๊ทœ์น™์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฌธํ™”๊ถŒ์ด _de-DE_๋กœ ์„ค์ •๋œ ๊ฒฝ์šฐ _CurrentCultureIgnoreCase_๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ํ•œ ๋ฌธ์ž ๋ฌธ์ž์—ด "รŸ"์™€ ๋‘ ๋ฌธ์ž ๋ฌธ์ž์—ด "SS"๊ฐ€ ๋™์ผํ•œ ๊ฒƒ์œผ๋กœ ๋น„๊ต๋ฉ๋‹ˆ๋‹ค.

@GrabYourPitchforks ๋‚˜๋Š” ์ฃผ๋กœ ์ด๋ฆ„ ์„ ํƒ์— ๋ฐ˜๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ๋ก€ ์ ‘๊ธฐ ์˜ˆ์ œ๋Š” ์ˆœ์ „ํžˆ ์œ ๋‹ˆ์ฝ”๋“œ(๋ฐ ์ผ๋ฐ˜์ ์œผ๋กœ ํ…์ŠคํŠธ)๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋ณต์žกํ•œ์ง€๋ฅผ ๊ฐ•์กฐํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. normalization ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋Š” ํ•œ ๊ฐ„๋‹จํ•œ ์ž‘์—…์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ํฌ๊ฒŒ ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚ด ์‚ฌ์šฉ ์‚ฌ๋ก€์—์„œ๋Š” ์–ด์จŒ๋“  ๋ชจ๋“  ๊ฒƒ์„ NFKD๋กœ ๋ณ€ํ™˜ํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ทธ ๋ฌธ์žฅ์ด ๋งž์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ ๊ณต๊ฐ„์€ U+0000 ~ U+10FFFF์ž…๋‹ˆ๋‹ค. ์œ ๋‹ˆ์ฝ”๋“œ๋Š” ์ด๋ก ์ ์œผ๋กœ ์–ธ์  ๊ฐ€๋Š” ๊ทธ ์ด์ƒ์œผ๋กœ ํ™•์žฅ๋  ์ˆ˜ ์žˆ์ง€๋งŒ UTF-8๊ณผ UTF-16์„ ๊นจ๋œจ๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์ธ์ฝ”๋”ฉ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ(๋˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ๊ด€์‹ฌ์ด ์žˆ๋Š” ๊ฒฝ์šฐ) ์ด๋ก ์ ์œผ๋กœ UTF-8 ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ตœ๋Œ€ 42๋น„ํŠธ(์ ‘๋‘์‚ฌ ๋ฐ”์ดํŠธ 0xFF ๋ฐ 6๋น„ํŠธ ํŽ˜์ด๋กœ๋“œ์˜ 7๋ฐ”์ดํŠธ)์—์„œ ์ž‘๋™ํ•˜๋ฉฐ ์›๋ž˜ ์ฒซ ๋ฒˆ์งธ ์‚ฌ์–‘ ์€ ์ „์ฒด 31๋น„ํŠธ๋ฅผ ๋‹ค๋ฃจ์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฒ”์šฉ ๋ฌธ์ž ์ง‘ํ•ฉ(UCS4)์˜ ์ด์ „ ๋ฒ„์ „์˜

UTF-16์˜ ๊ฒฝ์šฐ ์ƒํ™ฉ์ด ๋” ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๋“ค์€ 32๋น„ํŠธ ์ด์ƒ์— ๋Œ€ํ•ด "Escapes"๋กœ ์ƒ์œ„ ํ‰๋ฉด์˜ ์ฝ”๋“œ ํฌ์ธํŠธ๋ฅผ ์˜ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋น„ํ–‰๊ธฐ 3~13์€ ํ˜„์žฌ ์ •์˜๋˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ "๋‚ฎ์€ ๋Œ€๋ฆฌ ๋น„ํ–‰๊ธฐ"์™€ "๋†’์€ ๋Œ€๋ฆฌ ๋น„ํ–‰๊ธฐ"๋กœ ๋‘ ๊ฐœ๋ฅผ ์˜ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ 32๋น„ํŠธ ์ฝ”๋“œํฌ์ธํŠธ๋Š” 2๊ฐœ์˜ 16๋น„ํŠธ ๊ฐ’(๊ฐ ํ‰๋ฉด์— ํ•˜๋‚˜์”ฉ)์œผ๋กœ ๋ถ„ํ• ๋˜๊ณ  ๊ฐ ๊ฐ’์€ 32๋น„ํŠธ ์ฝ”๋“œํฌ์ธํŠธ๋ฅผ ์ธ์ฝ”๋”ฉํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ๊ฐ 16๋น„ํŠธ์˜ 4๊ฐœ ์ฝ”๋“œ ๋‹จ์œ„๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ 2๊ฐœ์˜ "ํด๋ž˜์‹" ๋Œ€๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์ฝ”๋”ฉ๋ฉ๋‹ˆ๋‹ค.

Btw, AFAICS, ์œ ๋‹ˆ์ฝ”๋“œ ์ปจ์†Œ์‹œ์—„์€ U+10FFFF ์ด์ƒ์˜ ์ฝ”๋“œํฌ์ธํŠธ๋ฅผ ํ• ๋‹นํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ๊ณต๊ฐœ์ ์œผ๋กœ ๋ฐํ˜”์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‹ค์ œ๋กœ๋Š” ๊ทธ๋Ÿฐ ์ผ์ด ์‹ค์ œ๋กœ ์ผ์–ด๋‚˜๊ธฐ ์ „์— ์ œ๊ฐ€ ์˜ค๋ž˜ ์€ํ‡ดํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. :๋ˆˆ์ง“:

ํ˜„์žฌ ๋งˆ์Šคํ„ฐ์— ์ฒดํฌ์ธ๋œ ์ด ์œ ํ˜•( System.Text.Rune )์€ "์œ ๋‹ˆ์ฝ”๋“œ ์Šค์นผ๋ผ ๊ฐ’"์— ๋งค์šฐ ๊ตฌ์ฒด์ ์œผ๋กœ ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค.

@GrabYourPitchforks ์„ค๋ช…ํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ตฌ์กฐ์ฒด๊ฐ€ ์ฝ”๋“œ ํฌ์ธํŠธ๋ฅผ ๋‚˜ํƒ€๋‚ด์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ทธ ์ด๋ฆ„์€ ์‹ค์ œ๋กœ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

UnicodeScalar ์ด๋ฆ„์ด ๋„ˆ๋ฌด ์• ๋งคํ•œ ๊ฒƒ ๊ฐ™์•„์š”...

@GrabYourPitchforks , ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ๋ฌด์—‡์„ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

@stephentoub 3.0์˜ ๊ธฐ๋ณธ Rune ์œ ํ˜•์— ๋Œ€ํ•ด ๊ณ„ํš๋œ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์€ ์—†์ง€๋งŒ @migueldeicaza ๋Š” ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ์™€ ๊ฐ™์€ ๊ฒƒ์„ ํฌํ•จํ•˜์—ฌ ์œ ํ˜•์˜ ๋ฒ”์œ„๋ฅผ ํ™•์žฅํ•˜๋Š” ์•„์ด๋””์–ด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. (์ธ๋ฐ•์Šค์— ์žˆ๋Š” ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๊ฒƒ์€ TextElementEnumerator ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋งค์šฐ ์˜ค๋ž˜๋œ ์œ ํ˜•์ž…๋‹ˆ๋‹ค.) ์ด๋Ÿฌํ•œ ์•„์ด๋””์–ด ์ค‘ ์ผ๋ถ€๋Š” ์ด ์Šค๋ ˆ๋“œ์—์„œ ๋ฌถ์˜€์ง€๋งŒ ์•„์ง ๊ตฌ์ฒด์ ์ธ ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค.

์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ์‹œ๋‚˜๋ฆฌ์˜ค์— ๋Œ€ํ•ด ๋” ๋…ผ์˜ํ•˜๊ธฐ๋ฅผ ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์ด ๋ฌธ์ œ๋ฅผ ์—ด์–ด๋‘˜ ์ˆ˜ ์žˆ๊ณ , ํŠน์ • ์ œ์•ˆ์„ ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์ƒˆ๋กœ์šด ๋ฌธ์ œ๋ฅผ ์—ด๋„๋ก ์ง€์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. TBH ๋‚˜๋Š” ๊ฐ•ํ•œ ์„ ํ˜ธ๋„๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฐ์‚ฌ ํ•ด์š”. Rune์ด ์ด๋ฏธ ๋„์ž…๋˜์—ˆ๊ณ  ์—ฌ๊ธฐ์— ์„ค๋ช…๋œ API(๋˜๋Š” ๊ทธ ๊ทผ์‚ฌ๊ฐ’)๊ฐ€ ์ด๋ฏธ ๋…ธ์ถœ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์ด ์ž‘์—…์„ ์ข…๋ฃŒํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ์ง€์›์€ ๋ณ„๋„์˜ ๋ฌธ์ œ๋ฅผ ํ†ตํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์ด๊ฒƒ์€ ์ด ์‹œ์ ์—์„œ ๋ณธ์งˆ์ ์œผ๋กœ ์•ˆ์ •ํ™”๋œ ๊ฒƒ์ž…๋‹ˆ๊นŒ? ์†”์งํžˆ ๋งํ•ด์„œ ์ด ๋‘๋ ค์šด ์ด๋ฆ„์€ ํ›Œ๋ฅญํ•˜๊ณ  ์ •ํ™•ํ•œ ์ถœ์ฒ˜์—์„œ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์œ ๋‹ˆ์ฝ”๋“œ ์ •๋ณด์™€ ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ธ์‡„๋˜์ง€ ์•Š๋Š” ๋ฌธ์ž์™€ ๋Œ€์กฐ์ ์œผ๋กœ ์ƒํ˜• ๋ฌธ์ž๋ฅผ ์•”์‹œํ•˜๋Š” ๋ถˆํ–‰ํ•œ ๋‰˜์•™์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ‰๋ฒ”ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์œ ๋‹ˆ์ฝ”๋“œ์— ๋Œ€ํ•ด ์ด๋ฏธ ๋‘๋ ค์šด ์ดํ•ด๋ฅผ ํ•˜๋Š” ๊ฒƒ์„ ์•…ํ™”์‹œํ‚ต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด ์ด ์‹œ์ ๊นŒ์ง€ ํ†ตํ•ฉ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ Rune ๋ถ€๋ถ„๊ณผ ์ด๋ฆ„์— ๋Œ€ํ•œ ์ผ๋ถ€ ์‚ฌ๋žŒ๋“ค์˜ ์˜๊ฒฌ ๋ถˆ์ผ์น˜์— ๋Œ€ํ•ด ์ฐจ์ž„ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ํ”Œ๋žœ 9์—์„œ Rune ๋ฅผ ์ฒ˜์Œ ๋งŒ๋‚ฌ๊ณ  ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ฒ˜๋Ÿผ Go์—์„œ ๊ทธ๊ฒƒ์„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. msdocs๊ฐ€ Rune ๋ฅผ ๋‚˜์—ดํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์„ ๋•Œ ๋‚˜๋Š” ์ฝ๊ธฐ ์ „์— ๊ทธ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ์ •ํ™•ํžˆ ์•Œ๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

Plan 9์™€ Go์˜ ๋‘ ๊ฐ€์ง€ ๊ฒฝ์šฐ์—๋Š” Rune ๋ผ๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์—ฌ UTF-8์„ ๋‹ด๋‹นํ•˜๋Š” ๊ฐœ์ธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๋“ค์ด ์ด๋Ÿฌํ•œ ์šฐ๋ ค์— ๋Œ€ํ•ด ์ด๋ฏธ ์ƒ๊ฐํ–ˆ๊ณ  ์—ฌ์ „ํžˆ Rune ๊ฐ€ ํ•ฉ๋ฆฌ์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋ฃฌ ๋ฌธ์ž๋Š” ์ผ๋ถ€ ์ „ํ†ต ์ฃผ์˜์ž๋ฅผ ์ œ์™ธํ•˜๊ณ  ๋” ์ด์ƒ ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์“ฐ๊ธฐ ์‹œ์Šคํ…œ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Rune ๋Š” ๋ณธ์งˆ์ ์œผ๋กœ ์—ฌ๊ธฐ์—์„œ ์ž์†Œ๋ฅผ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํ•ด๋‹น ์‹œ์Šคํ…œ์˜ ์ž์†Œ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค(์ œ์–ด ๋ฌธ์ž์™€ ๊ฐ™์€ ๊ฒฝ์šฐ ์ œ์™ธ.

๋„ค์ด๋ฐ์— ์•ฝ๊ฐ„์˜ ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. Runic์€ ๋„ˆ๋ฌด ์˜ค๋ž˜๋œ ์“ฐ๊ธฐ ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค. ํ‰๋ฒ”ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๊ทธ๊ฒƒ์„ ํ˜ผ๋™ํ•  ์ง€๋Š” ์˜์‹ฌ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ์ ์ ˆํ•œ ์œ ๋‹ˆ์ฝ”๋“œ "๋ฌธ์ž"์— ๋Œ€ํ•œ Rune ๋ผ๋Š” ์‚ฌ์‹ค์ƒ์˜ ํ‘œ์ค€์ด ์ด๋ฏธ ์ˆ˜์‹ญ ๋…„ ์ „์— ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

@์—”ํ† ๋ฏธ

๋ณธ์งˆ์ ์œผ๋กœ ์—ฌ๊ธฐ์—์„œ ์ž์†Œ๋ฅผ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ (์ œ์–ด ๋ฌธ์ž์™€ ๊ฐ™์€ ๊ฒฝ์šฐ ์ œ์™ธ.

์ด๊ฒƒ์€ ์‚ฌ์‹ค์ด ์•„๋‹™๋‹ˆ๋‹ค. ์œ ๋‹ˆ์ฝ”๋“œ์—๋Š” ์—ฌ๋Ÿฌ ์ž์†Œ(์ผ๋ฐ˜์ ์œผ๋กœ ๋ฌธ์ž ๋ฐ ๋ฐœ์Œ ๊ตฌ๋ณ„ ๋ถ€ํ˜ธ ์กฐํ•ฉ)๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์‚ฌ์ „ ๊ตฌ์„ฑ๋œ ์ฝ”๋“œ ํฌ์ธํŠธ๊ฐ€ ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์ด ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉฐ ์ด๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํ”„๋ž‘์Šค์–ด ๋ฐ ์ŠคํŽ˜์ธ์–ด์™€ ๊ฐ™์€ ์–ธ์–ด๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋ฉฐ ์ด๋Ÿฌํ•œ ์–ธ์–ด์˜ ๊ฑฐ์˜ ๋ชจ๋“  ์ปดํ“จํ„ฐํ™”๋œ ํ…์ŠคํŠธ๋Š” ์ด๋Ÿฌํ•œ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํฌ์ธํŠธ๋“ค.

๋ฐ˜๋Œ€๋กœ ๋‹จ์ผ ์ฝ”๋“œ ํฌ์ธํŠธ๊ฐ€ ํ•˜๋‚˜์˜ ์ž์†Œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒฝ์šฐ์—๋„ ๋Œ€๋ถ€๋ถ„์˜ ์ธ๋„ ์–ธ์–ด์—์„œ ํ…์ŠคํŠธ๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ํ•„์ˆ˜์ ์ธ _์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ_๋กœ ๊ฒฐํ•ฉํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ™”์‚ดํ‘œ ํ‚ค๋กœ ์ด๋™ํ•  ๋•Œ ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์‹ํ•˜๋Š” ๋‹จ์ผ ๋ฌธ์ž๋Š” ์ข…์ข… ์—ฌ๋Ÿฌ ์ฝ”๋“œ ํฌ์ธํŠธ์— ์ˆœ์ฐจ์ ์œผ๋กœ ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฝ”๋“œ ํฌ์ธํŠธ์™€ ์ž์†Œ ๋˜๋Š” ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ ์‚ฌ์ด์—๋Š” ์‰ฌ์šด ๋Œ€์‘์ด ์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ด ์‹œ์ ์—์„œ ๋ฌธ์ž๋ฅผ ์ด์ƒํ•˜๊ณ  ์—‰๋šฑํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•˜๋Š” ๋ฐ ์ต์ˆ™ํ•˜๋‹ค๋Š” ์ ์„ ๊ณ ๋ คํ•  ๋•Œ "๋ฌธ์ž"๋ผ๋„ ์•„๋งˆ๋„ ๋” ๋‚˜์€ ์ด๋ฆ„์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด "๋ฃฌ"์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์‹ํ•˜๋Š” ๋ฌธ์ž ๊ฒฝ๊ณ„๋ฅผ ํŒŒ์•…ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ํ”„๋กœ๊ทธ๋ž˜๋จธ์—๊ฒŒ ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค๋Š” ์ธ์ƒ์„ ์ค๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์—†์—ˆ์„ ๋•Œ ์ด๋ฏธ.

msdocs๊ฐ€ Rune์„ ๋‚˜์—ดํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์„ ๋•Œ ๋‚˜๋Š” ์ฝ๊ธฐ ์ „์— ๊ทธ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ์ •ํ™•ํžˆ ์•Œ๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

rune์ด๋ผ๋Š” ์ด๋ฆ„์ด ์ž์†Œ๋ฅผ ์ž˜ ์„ค๋ช…ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค๋Š” ์‚ฌ์‹ค์€ ๋‚ด๊ฐ€ ์—ฌ๊ธฐ์„œ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฌธ์ œ์— ๋Œ€ํ•œ ์•„์ฃผ ์ข‹์€ ์ฆ๊ฑฐ์ž…๋‹ˆ๋‹ค. "rune"์ด๋ผ๋Š” ์ด๋ฆ„์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ์—๊ฒŒ ๊ทธ๋Ÿฌํ•œ ๋Œ€์‘์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ธฐ ์‰ฝ๊ฒŒ ํ•จ์œผ๋กœ์จ ์ž˜๋ชป๋œ ๋ณด์•ˆ ๊ฐ๊ฐ์„ ์ค๋‹ˆ๋‹ค.

Plan 9์™€ Go์˜ ๋‘ ๊ฐ€์ง€ ๊ฒฝ์šฐ์—๋Š” Rune ๋ผ๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์—ฌ UTF-8์„ ๋‹ด๋‹นํ•˜๋Š” ๊ฐœ์ธ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ Ken Thompson๊ณผ Rob Pike๋ฅผ ์กด๊ฒฝํ•˜๋Š” ๋งŒํผ ์—ฌ๊ธฐ์—์„œ์˜ ๊ทธ๋“ค์˜ ์ž‘์—…์€ ๋ณธ์งˆ์ ์œผ๋กœ ์ผ๋ จ์˜ ๊ฐ€๋ณ€ ๊ธธ์ด ์ •์ˆ˜๋ฅผ ์ธ์ฝ”๋”ฉํ•˜๊ธฐ ์œ„ํ•œ ๋งค์šฐ ์˜๋ฆฌํ•œ ๊ณ„ํš์„ ๊ณ ์•ˆํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ์œ ๋‹ˆ์ฝ”๋“œ ์ „์ฒด์— ๋Œ€ํ•œ ์ „๋ฌธ๊ฐ€๊ฐ€ ์•„๋‹ˆ๋ฉฐ ๋‚˜๋Š” ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ๊ทธ๋“ค์—๊ฒŒ ๋งค์šฐ ๊ฐ•๋ ฅํ•˜๊ฒŒ ๋™์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ €๋„ ์œ ๋‹ˆ์ฝ”๋“œ ์ „๋ฌธ๊ฐ€๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ์ ์„ ์ธ์ •ํ•˜์ง€๋งŒ, ๊ถŒ์œ„์— ๋Œ€ํ•œ ํ˜ธ์†Œ๋ ฅ์ด ๋ณด์ด๋Š” ๊ฒƒ๋งŒํผ ๊ฐ•๋ ฅํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ ์ ˆํ•œ ์œ ๋‹ˆ์ฝ”๋“œ "๋ฌธ์ž"์— ๋Œ€ํ•œ ๋ฃฌ์˜ ์‚ฌ์‹ค์ƒ ํ‘œ์ค€์ด ์ˆ˜์‹ญ ๋…„์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

"ํ‘œ์ค€"์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๊นŒ? ๋Œ€๋ถ€๋ถ„ ์ด ๋‘ ๊ฐ€์ง€๊ฐ€ ์ด๋ฆ„์„ ๋ฐ€์–ด๋ถ™์˜€๊ณ  Nim๊ณผ ๊ฐ™์€ ๋ช‡ ๊ฐ€์ง€ ์‚ฌ์†Œํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๊ฐ€ Go์—์„œ ์ด ์ด๋ฆ„์„ ์ฑ„ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฌผ๋ก  ์„ ํƒ, ํ™”์‚ดํ‘œ ํ‚ค ์ด๋™, ์ž์†Œ ๋˜๋Š” ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ์˜ ์˜๋ฏธ์—์„œ ์ฝ”๋“œ ํฌ์ธํŠธ๊ฐ€ ๋‹จ์ผ "์ ์ ˆํ•œ ์œ ๋‹ˆ์ฝ”๋“œ ๋ฌธ์ž"๋ฅผ ๋‚˜ํƒ€๋‚ด์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ๋‹ค์‹œ ๋ฐ˜๋ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

...๋ณธ์งˆ์ ์œผ๋กœ ์—ฌ๊ธฐ์—์„œ ์ž์†Œ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค...

์˜ˆ, ์ •ํ™•ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ๋Œ€๋žต์ ์œผ๋กœ ์ถฉ๋ถ„ํžˆ ๊ฐ€๊น์Šต๋‹ˆ๋‹ค. ์ ์–ด๋„ ์–ธ์–ดํ•™์—์„œ ์ •์˜๋˜๋Š” ๋ฌธ์ž์†Œ๋Š” ์“ฐ๊ธฐ ์ฒด๊ณ„๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  ์Œ์†Œ๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์ฒ ์ž๋ฒ• ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ๋“ค์€ 1:1์ด ์•„๋‹™๋‹ˆ๋‹ค. ์Œ์ ˆ ๋ฐ ๋กœ๊ณ  ์Œ์ ˆ์—์„œ ๋‹จ์ผ ์ž์†Œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์ž์Œ-๋ชจ์Œ ์Œ์œผ๋กœ ์—ฌ๋Ÿฌ ์Œ์†Œ๋ฅผ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋Œ€๋กœ ์•ŒํŒŒ๋ฒณ์ˆœ์œผ๋กœ ์–ธ์–ด์—๋Š” ํŠน์ • ๋‹จ์–ด์— ๋”ฐ๋ผ ์˜์–ด์˜ "th"๊ฐ€ ๊ณ ๋Œ€ eth์™€ thorn์„ ๋‹ด๋‹นํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด ๋‹จ์ผ ์Œ์†Œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์—ฌ๋Ÿฌ ์ž์†Œ์˜ ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ 'รก'์™€ ๊ฐ™์€ ๋ฌธ์ž๊ฐ€ ๊ณ ์œ ํ•œ ๋ฌธ์ž์ธ์ง€ ๋˜๋Š” ์•…์„ผํŠธ๊ฐ€ ์žˆ๋Š” 'a'์ธ์ง€์— ๋Œ€ํ•ด ์–ธ์–ด ๊ฐ„์— ์ผ์น˜๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ˆ˜์ฒœ ๋…„์ด ์ง€๋‚œ ์–ธ์–ด์˜ ์ผ๊ด€์„ฑ์กฐ์ฐจ ํ™•๋ฆฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ทธ ์œ„์— ์™„๋ฒฝํ•˜๊ฒŒ ์ผ๊ด€๋œ ์ถ”๊ฐ€๋ฅผํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ์ธ์ฝ”๋”ฉ์ž…๋‹ˆ๋‹ค.

๋‹น์‹ ์ด ๋งค์šฐ ์—„๊ฒฉํ•œ ์˜๋ฏธ๋ก ์„ ์ฃผ์žฅํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— UNICODE๊ฐ€ "์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ"๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฒƒ์€ ์–ธ์–ดํ•™์—์„œ ์ข…์ข… ๋‹จ์ผ ์ž์†Œ์— ๋ถˆ๊ณผํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ž˜๋ชป๋œ ์œ ๋‹ˆ์ฝ”๋“œ์ž…๋‹ˆ๊นŒ? ์•„๋‹ˆ์š”. ์ด๊ฒƒ์€ UNICODE์—์„œ ์ด๋ฆ„์„ ๋ฐ”๊ฟ”์•ผ ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๊นŒ? ์ด์œ ์—†์ด? ์ปจํ…์ŠคํŠธ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ•„๋“œ์—๋Š” ๊ณ ์œ ํ•œ ์šฉ์–ด๊ฐ€ ์žˆ์œผ๋ฉฐ ๋‹จ์ผ ํ•„๋“œ์— ์œตํ•ฉ์ด ์—†๋Š” ํ•œ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ ์ด๋ฆ„์ด ๋„ˆ๋ฌด ํฐ ๊ฑฐ๋ž˜๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Msdocs๋Š” ์š”์•ฝ์— Rune ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๋ช…ํ™•ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๋ฌธ์„œ๋ฅผ ์ฝ์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ทธ๊ฒƒ์€ ๊ทธ๋“ค ์ž์‹ ์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์€ 'Stream'์— ๊ฒฉ๋ ฌํ•˜๊ฒŒ ๋ฐ˜์‘ํ•˜์ง€ ์•Š๊ณ  "์˜ค, ํ•˜์ง€๋งŒ ์‚ฌ๋žŒ๋“ค์ด ๊ทธ๊ฒƒ์„ ์ž‘์€ ๊ฐ•์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค๋ฉด ๊ทธ๊ฒƒ์€ ์ด๋ฏธ ๊ฐ™์€ ์ด๋ฆ„์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—"์™€ ๊ฐ™์€ ๋ง๋„ ์•ˆ๋˜๋Š” ์†Œ๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋‹ˆ์š”.

@Serentty @Entomy ๋‘ ์‚ฌ๋žŒ ๋ชจ๋‘ ์‹ค์ œ ์œ ๋‹ˆ์ฝ”๋“œ ๊ฐœ๋… "ํ™•์žฅ๋œ ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ"๋ฅผ ๋…ธ์ถœํ•˜๋Š” StringInfo ํด๋ž˜์Šค ์— ๊ด€์‹ฌ์ด ์žˆ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. StringInfo ์œ ํ˜•์€ ์ƒ๋‹นํžˆ ์˜ค๋ž˜๋˜์—ˆ๊ณ  ๊ฒฐ๊ณผ์ ์œผ๋กœ ๋งค์šฐ ์˜ค๋ž˜๋œ ๋ฒ„์ „์˜ ์œ ๋‹ˆ์ฝ”๋“œ ํ‘œ์ค€์„ ๊ตฌํ˜„ํ•˜์ง€๋งŒ UAX #29, Sec.

์˜ˆ, ์ •ํ™•ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ๋Œ€๋žต์ ์œผ๋กœ ์ถฉ๋ถ„ํžˆ ๊ฐ€๊น์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ํ•ฉ์„ฑ๋œ ํ‘œํ˜„ ๋Œ€ ๋ถ„ํ•ด๋œ ํ‘œํ˜„์˜ ๋ฌธ์ œ๊ฐ€ ์ด๊ฒƒ์„ ์‚ฌ์‹ค์ด ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ปดํ“จํŒ… ๊ด€๋ จ ์ •์˜์™€ ๋‹ฌ๋ฆฌ ์—ฌ๊ธฐ์—์„œ ๋ฌธ์ž์†Œ์˜ ์–ธ์–ด์  ์ •์˜์— ๋”ฐ๋ผ ๊ฐ„๋‹ค๋ฉด ํ•œ๊ณผ ํ•œ์€ ์ •ํ™•ํžˆ ๊ฐ™์€ ์ž์†Œ ์‹œํ€€์Šค์ž…๋‹ˆ๋‹ค(์„ธ ๊ฐœ์˜ ํ•œ๊ธ€ ์ž๋ชจ๋Š” ์Œ์ ˆ _han_์„ ์„ธ๊ทธ๋จผํŠธ HAN์œผ๋กœ ๋‚˜ํƒ€๋ƒ„). ๊ทธ๋Ÿฌ๋‚˜ ์ฒซ ๋ฒˆ์งธ๋Š” ํ•˜๋‚˜์˜ ์ฝ”๋“œ ํฌ์ธํŠธ์ธ ๋ฐ˜๋ฉด ๋‘ ๋ฒˆ์งธ๋Š” 3๊ฐœ์˜ ์‹œํ€€์Šค์ž…๋‹ˆ๋‹ค.

ํ•„๋“œ์—๋Š” ๊ณ ์œ ํ•œ ์šฉ์–ด๊ฐ€ ์žˆ์œผ๋ฉฐ ๋‹จ์ผ ํ•„๋“œ์— ์œตํ•ฉ์ด ์—†๋Š” ํ•œ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋ฐ”๋กœ ์ œ ์š”์ ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์œ ๋‹ˆ์ฝ”๋“œ๋Š” ์ž์ฒด ์šฉ์–ด๊ฐ€ ์žˆ๋Š” ์ •๋ง ๋ณต์žกํ•œ ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ •ํ™•ํžˆ ์ •๋ ฌ๋˜์ง€ ์•Š์„ ๋•Œ ์ผ์ข…์˜ ๋ฐ˜์ฏค ๊ตฌ์šด "์ง๊ด€์ ์ธ" ์šฉ์–ด๋ฅผ ๊ฐ•์ œ๋กœ ์ ์šฉํ•˜๋ ค๊ณ  ํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ฝ”๋“œ ํฌ์ธํŠธ๋Š” ์ฝ”๋“œ ํฌ์ธํŠธ์ž…๋‹ˆ๋‹ค. ์–ธ์–ด์  ์œ ์‚ฌ์„ฑ์ด ์—†์œผ๋ฉฐ 75%์˜ ์ •ํ™•๋„๋งŒ ์œ ์ง€ํ•˜๋ฉด์„œ ์ง๊ด€์ ์œผ๋กœ ํ•˜๋ ค๊ณ  ํ•˜๋Š” ๊ฒƒ์€ C#์ด ์—ฌ์ „ํžˆ ๋ณต๊ตฌํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๋Š” ๋™์ผํ•œ ์ข…๋ฅ˜์˜ ์žฌ๋‚œ์— ๋Œ€ํ•œ ๋ ˆ์‹œํ”ผ์ž…๋‹ˆ๋‹ค.

๋‹น์‹ ์ด ๋งค์šฐ ์—„๊ฒฉํ•œ ์˜๋ฏธ๋ก ์„ ์ฃผ์žฅํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— UNICODE๊ฐ€ "์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ"๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฒƒ์€ ์–ธ์–ดํ•™์—์„œ ์ข…์ข… ๋‹จ์ผ ์ž์†Œ์— ๋ถˆ๊ณผํ•ฉ๋‹ˆ๋‹ค.

ํ‘œ์ค€์—์„œ ํด๋Ÿฌ์Šคํ„ฐ๋Š” ๋‹จ์ผ ์ž์†Œ๋กœ๋งŒ ๊ตฌ์„ฑ๋˜๋„๋ก ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ์•„๋ฌด ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. _cluster_๋Š” ํ…์ŠคํŠธ ์„ ํƒ ๋ฐ ์ปค์„œ ์ด๋™์˜ ๋‹จ์œ„์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ ์ด๋ฆ„์ด ๋„ˆ๋ฌด ํฐ ๊ฑฐ๋ž˜๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Msdocs๋Š” ์š”์•ฝ์—์„œ Rune์ด ๋ฌด์—‡์ธ์ง€ ๋ช…ํ™•ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๋ฌธ์„œ๋ฅผ ์ฝ์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ทธ๊ฒƒ์€ ๊ทธ๋“ค ์ž์‹ ์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ž˜๋ชป๋œ ๋””์ž์ธ ๊ฒฐ์ •์„ ๋ฐฉ์–ดํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ˜๋ณต์ ์œผ๋กœ ๋‚˜์˜ค๋Š” "ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ๋” ๋˜‘๋˜‘ํ•ด์•ผ ํ•œ๋‹ค"๋Š” ์ฃผ์žฅ์ž…๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋ฌธ์„œ๋ฅผ ์ฝ๊ณ  ์–ด์จŒ๋“  ๋ฃฌ์ด ์œ ๋‹ˆ์ฝ”๋“œ ์ฝ”๋“œ ํฌ์ธํŠธ๋ผ๋Š” ๊ฒƒ์„ ๋ฐฐ์›Œ์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์ฒ˜์Œ์— ๋” "์ง๊ด€์ ์ธ" ์ด๋ฆ„์ด๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ์š”์ ์ด ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์—ฌ๊ธฐ์„œ ์ฃผ์žฅ์€ "์ฝ”๋“œ ํฌ์ธํŠธ"๊ฐ€ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ธฐ ๋•Œ๋ฌธ์— ๋ณด๋‹ค ์ง๊ด€์ ์ธ ์ด๋ฆ„์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ด์ง€๋งŒ, ์ด๋ฆ„์ด ์˜คํ•ด์˜ ์†Œ์ง€๊ฐ€ ์žˆ๋‹ค๋Š” ๋ฌธ์ œ์— ์ง๋ฉดํ–ˆ์„ ๋•Œ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์–ด์จŒ๋“  ์ฝ”๋“œ ํฌ์ธํŠธ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•Œ์•„์•ผ ํ•œ๋‹ค๋Š” ์ฃผ์žฅ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ฌธ์„œ๋ฅผ ์ฝ๋Š” ๊ฒƒ์—์„œ. ๊ทธ๋ ‡๋‹ค๋ฉด ๊ทธ๋ƒฅ CodePoint ์œ ํ˜•์„ ํ˜ธ์ถœํ•˜๊ณ  ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋” ์‰ฝ๊ฒŒ ์ฐพ์•„๋ณด๊ณ  ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋„๋ก ํ•˜์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ .NET ๋ฌธ์„œ๊ฐ€ ์ฒ˜์Œ์— ์œ ๋‹ˆ์ฝ”๋“œ์™€ ๊ด€๋ จํ•˜์—ฌ ๋งค์šฐ ๋”์ฐํ•˜๋‹ค๋Š” ๋ฌธ์ œ๋ฅผ ์ œ์ณ๋‘๊ณ , "16๋น„ํŠธ ์œ ๋‹ˆ์ฝ”๋“œ ๋ฌธ์ž"์˜ ์„ธ๊ณ„์—์„œ ๋Œ€๋ฆฌ ์Œ์„ ์‚ฌํ›„ ๊ณ ๋ ค ์‚ฌํ•ญ์œผ๋กœ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ž˜๋ชป๋œ ๋””์ž์ธ ๊ฒฐ์ •์„ ๋ฐฉ์–ดํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ˜๋ณต์ ์œผ๋กœ ๋‚˜์˜ค๋Š” "ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ๋” ๋˜‘๋˜‘ํ•ด์•ผ ํ•œ๋‹ค"๋Š” ์ฃผ์žฅ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์„ ๋งํ•œ ์ ์ด ์—†๋‹ค.

์—ฌ๊ธฐ์„œ ์ฃผ์žฅ์€ "์ฝ”๋“œ ํฌ์ธํŠธ"๊ฐ€ ํ˜ผ๋ž€์Šค๋Ÿฝ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋„ ์ด ๋ง์„ ํ•œ ์ ์ด ์—†๋‹ค.

์‚ฌ๋žŒ๋“ค์€ 'Stream'์— ๊ฒฉ๋ ฌํ•˜๊ฒŒ ๋ฐ˜์‘ํ•˜์ง€ ์•Š๊ณ  "์˜ค, ํ•˜์ง€๋งŒ ์‚ฌ๋žŒ๋“ค์ด ๊ทธ๊ฒƒ์„ ์ž‘์€ ๊ฐ•์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค๋ฉด ๊ทธ๊ฒƒ์€ ์ด๋ฏธ ๊ฐ™์€ ์ด๋ฆ„์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—"์™€ ๊ฐ™์€ ๋ง๋„ ์•ˆ๋˜๋Š” ์†Œ๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋‹ˆ์š”.

๋‚˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ Rune ๊ฐ€ ํŠนํžˆ ๋ฃฌ ๋ฌธ์ž๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์„ ๋งŒํผ ์ถฉ๋ถ„ํžˆ ๋˜‘๋˜‘ํ•˜๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งˆ์น˜ ๊ทธ๋“ค์ด Stream ๊ฐ€ ์ž‘์€ ๊ฐ•์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์„ ์•„๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์„ ๋ฐ˜๋ณตํ•˜์ž

๋‚˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ด๊ฒƒ์„ ์•Œ์•„๋‚ผ ๋งŒํผ ์ถฉ๋ถ„ํžˆ ๋˜‘๋˜‘ํ•˜๋‹ค๊ณ  ๋งํ•˜๊ณ  ์žˆ๋‹ค. ๋‹น์‹ ์€ ๋‚ด ์ž…์— ๋‹จ์–ด๋ฅผ ๋„ฃ์–ด.

๋‚˜๋Š” ๊ทธ ์ด๋ฆ„์ด ๋„ˆ๋ฌด ํฐ ๊ฑฐ๋ž˜๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Msdocs๋Š” ์š”์•ฝ์—์„œ Rune์ด ๋ฌด์—‡์ธ์ง€ ๋ช…ํ™•ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๋ฌธ์„œ๋ฅผ ์ฝ์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ทธ๊ฒƒ์€ ๊ทธ๋“ค ์ž์‹ ์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. "๋ฃฌ"์ด๋ผ๋Š” ์ด๋ฆ„์— ์ฐฌ์„ฑํ•˜๋Š” ์ฃผ์žฅ์€ ์ง๊ด€๊ณผ ์ž์†Œ ๊ฐœ๋…๊ณผ์˜ ์ง๊ด€์ ์ธ ์—ฐ๊ฒฐ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๋‘ ์‚ฌ๋žŒ์ด ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์„ ์ •๋„๋กœ ๋ฐ€์ ‘ํ•˜๊ฒŒ ์ •๋ ฌ๋˜์–ด ์žˆ๋‹ค๊ณ  ์ฃผ์žฅํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๊ทธ ์ง๊ด€์ด ํ‹€๋ ธ๊ณ  ํ†ต์‹ ์ด ๋งค์šฐ ๋‚˜์  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ชจ๋“  ๋ฐฉ๋ฒ•์„ ์ง€์ ํ–ˆ์„ ๋•Œ, ๋‹น์‹ ์˜ ๋Œ€๋‹ต์€ ๋ณธ์งˆ์ ์œผ๋กœ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์–ด์จŒ๋“  ๋ฌธ์„œ๋ฅผ ์ฝ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ค‘์š”ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋‚ด๊ฐ€ "ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ๋” ๋˜‘๋˜‘ํ•ด์ ธ์•ผ ํ•œ๋‹ค"๋Š” ๋ง์˜ ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ๋ฌธ์„œํ™”๋Š” ์ด๋ฆ„์— ๋Œ€ํ•œ ๋ ˆ๊ฑฐ์‹œ ์ด์œ ๊ฐ€ ์—†์„ ๋•Œ ์˜คํ•ด์˜ ์†Œ์ง€๊ฐ€ ์žˆ๋Š” ์ด๋ฆ„์— ๋Œ€ํ•œ ๋ณ€๋ช…์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋‚˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ Rune ๊ฐ€ ํŠนํžˆ ๋ฃฌ ๋ฌธ์ž๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์„ ๋งŒํผ ์ถฉ๋ถ„ํžˆ ๋˜‘๋˜‘ํ•˜๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งˆ์น˜ ๊ทธ๋“ค์ด Stream ๊ฐ€ ์ž‘์€ ๊ฐ•์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์„ ์•„๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๋‚ด ์ฃผ์žฅ์€ ์‚ฌ๋žŒ๋“ค์ด ๊ทธ๊ฒƒ์„ ๋ฃฌ ๋ฌธ์ž์™€ ํ˜ผ๋™ํ•  ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋‚ด ์ฃผ์žฅ์€ ์‚ฌ๋žŒ๋“ค์ด ๋‹น์‹ ์˜ ์ฃผ์žฅ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋ชจ๋‘ ์ฝ”๋“œ ํฌ์ธํŠธ์™€ ๋งค์šฐ ๋‚˜์œ ์ƒ๊ด€ ๊ด€๊ณ„๋ฅผ ๊ฐ–๋Š” ๊ธ€๋ฆฌํ”„, ์ž์†Œ ๋ฐ ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ์™€ ํ˜ผ๋™ํ•  ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ด๊ฒƒ์„ ์•Œ์•„๋‚ผ ๋งŒํผ ์ถฉ๋ถ„ํžˆ ๋˜‘๋˜‘ํ•˜๋‹ค๊ณ  ๋งํ•˜๊ณ  ์žˆ๋‹ค. ๋‹น์‹ ์€ ๋‚ด ์ž…์— ๋‹จ์–ด๋ฅผ ๋„ฃ์–ด.

๊ทธ๋“ค์ด ์‹ค์ œ ๊ฒŒ๋ฅด๋งŒ ๋ฃฌ์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์„ ์•Œ์•„๋‚ผ ๋งŒํผ ๋˜‘๋˜‘ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ๋“ค์ด ๊ธ€๋ฆฌํ”„, ์ž์†Œ ๋˜๋Š” ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์„ ์•Œ์•„๋‚ด๋ ค๋ฉด? ๋Œ€๋ถ€๋ถ„์˜ ์†Œํ”„ํŠธ์›จ์–ด์—์„œ ์œ ๋‹ˆ์ฝ”๋“œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํ’ˆ์งˆ์— ๋Œ€ํ•œ ๋‚˜์˜ ์‹ค์ œ ๊ฒฝํ—˜์€ ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ๋žŒ๋“ค์ด ๋ฌธ์„œ๋ฅผ ์ฝ์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ทธ๊ฒƒ์€ ๊ทธ๋“ค ์ž์‹ ์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

์˜ˆ, ์ €๋Š” ์ด๊ฒƒ์„ ์ง€์ง€ํ•ฉ๋‹ˆ๋‹ค. ์ง€๋Šฅ์ด ๋ถ€์กฑํ•ด์„œ๊ฐ€ ์•„๋‹ˆ๋ผ ์„ฑ๊ธ‰ํ•œ ๊ฐ€์ •์„ ํ•˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ String ๊ฐ€ ์‹ค์„ ๊ผฌ์•„์„œ ๋งŒ๋“  ๊ฐ•ํ•˜๊ณ  ์–‡์€ ๋ฐง์ค„ ์กฐ๊ฐ์„ ์˜๋ฏธํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค๋ฉด, ์˜ˆ, ๊ทธ๊ฒƒ์€ ๊ทธ๊ฒƒ์ด String ๋ผ๋Š” ์ด๋ฆ„์— ๋ฌธ์ œ๋กœ ๊ฐ„์ฃผ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. .

ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ Char ๊ฐ€ ์ˆฏ๊ณผ ๊ฐ™์€ ํƒ„ ์žฌ๋ฃŒ ๋˜๋Š” ํŠน์ • ์œ ํ˜•์˜ ์†ก์–ด๋ฅผ ์˜๋ฏธํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด Char ์ด๋ฆ„์˜ ๋ฌธ์ œ๋กœ ๊ฐ„์ฃผ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ character ๊ฐ€ ์Šคํ† ๋ฆฌํ…”๋ง์— ์‚ฌ์šฉ๋˜๋Š” ์ผ๋ จ์˜ ์ •์‹ ์ , ์œค๋ฆฌ์  ํŠน์„ฑ์˜ ๋ฌ˜์‚ฌ๋ฅผ ์˜๋ฏธํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด character ๋ผ๋Š” ์ด๋ฆ„์˜ ๋ฌธ์ œ๋กœ ๊ฐ„์ฃผ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ๋“ค์€ ๋ชจ๋‘ ํ…์ŠคํŠธ/์–ธ์–ด ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ๋ชจ๋‘ ๋‹ค๋ฅธ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ์ž˜ ์ ์‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์šฉ์–ด๋Š” ํ•ด๋‹น ๋ถ„์•ผ์—์„œ ํ™•๋ฆฝ๋œ ๊ด€์Šต์ธ ๋‹น์‚ฌ ์šฉ์–ด๋กœ ์ธํ•ด ์‚ฌ์‹ค์ƒ์˜ ํ‘œ์ค€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ด๊ฒƒ์„ ๋”ฐ๋ฅผ ๋งŒํผ ์ถฉ๋ถ„ํžˆ ๋˜‘๋˜‘ํ•˜๋‹ค๋Š” ํ™•๋ฆฝ๋œ ์„ ๋ก€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹น์‹ ์€ ๋‘ ์‚ฌ๋žŒ์ด ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์„ ์ •๋„๋กœ ๋ฐ€์ ‘ํ•˜๊ฒŒ ์ •๋ ฌ๋˜์–ด ์žˆ๋‹ค๊ณ  ์ฃผ์žฅํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ, ์ด๊ฒƒ์€ GitHub์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ ๋งˆ๊ฐ๋œ ๋ฌธ์ œ์—์„œ ์ด๋ฆ„์— ํ™•๋ฆฝ๋œ ์„ ๋ก€๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Rune ๊ฐ€ ๊ดœ์ฐฎ๋‹ค๊ณ  ์ƒ๊ฐํ•œ ์ด์œ ์— ๋Œ€ํ•œ ์ƒ๊ฐ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ณณ์€ ๊ด‘๋ฒ”์œ„ํ•œ ์ •์˜์™€ ์‹ ์ค‘ํ•˜๊ฒŒ ์„ ํƒํ•œ ๋‹จ์–ด๋กœ ๊ฐ€๋“ ์ฐฌ ๋…ผ๋ฌธ์„ ์“ฐ๊ธฐ ์œ„ํ•œ ์žฅ์†Œ๋‚˜ ๋งฅ๋ฝ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, UTF-8 ๋””์ฝ”๋”์— ๋Œ€ํ•œ PR์„ ์ž…๋ ฅํ•˜๋Š” ๊ฒฝ์šฐ ๋Œ€์ฒด ์ ‘๊ทผ ๋ฐฉ์‹๋ณด๋‹ค Hoehrmann DFA๋ฅผ ๊ตฌํ˜„ํ•œ ์ด์œ ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์„ค๋ช…ํ•˜์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค. ์ €๋Š” "์—ฌ๊ธฐ ์žˆ์Šต๋‹ˆ๋‹ค, ์—ฌ๊ธฐ์— ์ž‘๋™ํ•˜๋Š” ์ฆ๊ฑฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ๋‚ด๊ฐ€ ์™œ ์ด๊ฒƒ์„ ์‚ฌ์šฉํ–ˆ๋Š”์ง€ ๋’ท๋ฐ›์นจํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฒค์น˜๋งˆํฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค"๋ผ๊ณ  ๋งํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚ด ์ฃผ์žฅ์€ ์‚ฌ๋žŒ๋“ค์ด ๊ธ€๋ฆฌํ”„, ์ž์†Œ ๋ฐ ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ์™€ ํ˜ผ๋™ํ•  ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•ž์„œ ์–ธ๊ธ‰ํ•œ ๊ฒƒ๊ณผ Tree , Heap , Table , Key , Socket , Port ์ค‘ ์–ด๋Š ๊ฒƒ๋„ ํ˜ผ๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋งค์šฐ ๋ถˆํ•ฉ๋ฆฌํ•œ ์ฃผ์žฅ์ž…๋‹ˆ๋‹ค. ํ•œ ์กฐ๊ฐ์˜ ์‹ค๊ณผ ํ…์ŠคํŠธ์˜ ๋ฌธ์ž์—ด์€ ์‰ฝ๊ฒŒ ํ˜ผ๋™๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ‚ค๊ฐ€ ํฐ ์‹๋ฌผ๊ณผ ๋‚˜๋ฌด ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋Š” ์‰ฝ๊ฒŒ ํ˜ผ๋™๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์— ์ฝ”๋“œ ํฌ์ธํŠธ๋Š” ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋งค์šฐ ์ž˜ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฐœ๋…์ด๋ฉฐ ์šฐ๋ฆฌ๊ฐ€ ๋…ผ์˜ํ•œ ๋‹ค๋ฅธ ๋ชจ๋“  ๊ฐœ๋…๊ณผ ๋Š์ž„์—†์ด ํ˜ผ๋™๋ฉ๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์€ ๋‹น์‹ ์ด ๋งํ–ˆ๋“ฏ์ด ๋ฌธ์„œ๋ฅผ ์ฝ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ฝ”๋“œ ํฌ์ธํŠธ์— ๋Œ€ํ•ด ๊ณ ์œ ํ•œ "์˜๋ฆฌํ•œ" ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๋Š” ์–ธ์–ด๋Š” _์‹ค์ œ ์œ ๋‹ˆ์ฝ”๋“œ ๋ฌธ์„œ_์˜ ์ง€์‹์„ ํ•ด๋‹น ์–ธ์–ด์— ์ ์šฉํ•˜๋Š” ๊ฒƒ์„ ํ›จ์”ฌ ๋” ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์€ ์ €๋ฅผ ์ด๋ ‡๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์šฉ์–ด๋Š” ํ•ด๋‹น ๋ถ„์•ผ์—์„œ ํ™•๋ฆฝ๋œ ๊ด€์Šต์ธ ๋‹น์‚ฌ ์šฉ์–ด๋กœ ์ธํ•ด ์‚ฌ์‹ค์ƒ์˜ ํ‘œ์ค€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์ด ๋ชจ๋“  ๊ฒƒ์˜ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค. ๋‹น์‹ ์€ "๋ฃฌ"์ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๋„๋ฆฌ ์ดํ•ด๋˜๋Š” ์ฝ”๋“œ ํฌ์ธํŠธ์— ๋Œ€ํ•œ ์ž˜ ์ •๋ฆฝ๋œ ์šฉ์–ด์ด๊ฑฐ๋‚˜ ๊ทธ๋ž˜์•ผ ํ•œ๋‹ค๊ณ  ์ฃผ์žฅํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ „์ž๋ผ๋ฉด Go ์ด์™ธ์˜ ์ฃผ์š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์— ๊ฒฝํ—˜์ด ์žˆ๋Š” ์ผ๋ฐ˜ ํ”„๋กœ๊ทธ๋ž˜๋จธ์—๊ฒŒ ๋“ค์–ด๋ณธ ์ ์ด ์žˆ๋Š”์ง€ ๋ฌผ์–ด๋ณด์‹ญ์‹œ์˜ค. ํ›„์ž๋ผ๋ฉด ๊ณ ๋„๋กœ ์ˆ™๋ จ๋œ ๊ฐœ๋ฐœ์ž๋ผ๋„ ์ž์ฃผ ์˜คํ•ดํ•˜๋Š” ์ด๋ฏธ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ณ  ์ž˜ ์ดํ•ด๋˜์ง€ ์•Š๋Š” ์ƒํ™ฉ์—์„œ ๊ณต์‹ ์œ ๋‹ˆ์ฝ”๋“œ ์šฉ์–ด์™€ ๊ฒฝ์Ÿํ•˜๋Š” ์š”์ ์„ ๋ฌป๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

@Entomy ์™ธ๋ถ€์ธ ์ž…๋ ฅ: ๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ ๊ท€ํ•˜์˜ ์ „์ฒด ์ฃผ์žฅ์€ 'ํ˜ผ๋ž€์Šค๋Ÿฝ๊ณ  ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋ ‡๊ฒŒ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ณ  ๋‚˜์˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค'์ž…๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ? ๋Œ€์‹ ์— ์‹ค์ œ๋กœ ์ข‹์ง€ ์•Š์€ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์œ ๋‹ˆ์ฝ”๋“œ์˜ ์ด๋ฆ„๊ณผ ์ •ํ™•ํžˆ ๊ฐ™์€ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋Š” ๋ฐ ์–ด๋–ค ๋ฌธ์ œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?
๋˜ํ•œ ๋ฃฌ์€ ์ผ๋ฐ˜์ ์ธ ์ปดํ“จํŒ… ๋ถ„์•ผ์—์„œ ์ฝ”๋“œ ํฌ์ธํŠธ๋‚˜ ์ž์†Œ ๋˜๋Š” ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. Google์—์„œ 'Unicode runes'๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ฉด ์ฝ”๋“œ ํฌ์ธํŠธ์™€ ๊ด€๋ จ๋œ ๋ชจ๋“  ๊ฒƒ์ด 2ํŽ˜์ด์ง€๊นŒ์ง€ ํ‘œ์‹œ๋˜์ง€ ์•Š๊ณ  ๊ทธ๋•Œ๋„ godoc/Nim ๋งํฌ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋” ํŽธํ•  ์ˆ˜ ์žˆ๋Š” DuckDuckGo์—์„œ๋„ ์—ฌ์ „ํžˆ 2ํŽ˜์ด์ง€์˜ ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‚ด๊ฐ€ ๋ณธ ์ด๋ฆ„์— ๋Œ€ํ•ด ๋‚จ์€ ์œ ์ผํ•œ ์ฃผ์žฅ์€ ์ฝ”๋“œ ํฌ์ธํŠธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ์ด ์ง๊ด€์  ์ด์ง€๋งŒ . ๊ทธ๊ฒƒ์ด ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ ๋˜๋Š” ์•„๋งˆ๋„ ๋‹จ์ง€ ์ž์†Œ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค๋Š” ๊ฒƒ์€ ์ง๊ด€์ ์ž…๋‹ˆ๋‹ค.
์ถœ์ฒ˜: ์ €๋Š” Go๋ฅผ ์‚ฌ์šฉํ•ด ์™”์œผ๋ฉฐ 4๋…„ ํ›„ ์ด ํ˜ธ๋ฅผ ์ฝ์„ ๋•Œ๊นŒ์ง€ ์ด๊ฒƒ์ด ์ž์†Œ์ธ ์ค„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

(๊ทธ๋ฆฌ๊ณ  '์ถฉ๋ถ„ํžˆ ๊ฐ€๊น๊ธฐ' ๋•Œ๋ฌธ์— ์ž์†Œ๋ฅผ ์ œ์•ˆํ•ด๋„ ๊ดœ์ฐฎ๋‹ค๋Š” ๋ง์€ 16๋น„ํŠธ ๋ฌธ์ž๊ฐ€ ์ถฉ๋ถ„ํžˆ ๊ฐ€๊น๋‹ค๋Š” ๊ฒƒ์„ ์ƒ๊ธฐ์‹œ์ผœ์ค๋‹ˆ๋‹ค.)
์˜ˆ, ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋” ๋˜‘๋˜‘ํ•˜๊ณ  ๋” ๋งŽ์€ ๋ฌธ์„œ๋ฅผ ์ฝ๋Š”๋‹ค๋ฉด ์˜๋ฏธ ์žˆ๋Š” ์ด๋ฆ„์ด๋‚˜ ์œ ํ˜•์ด ์ „ํ˜€ ํ•„์š”ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์€ char ๋Œ€์‹  int๋กœ ์ฝ”๋“œ ํฌ์ธํŠธ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋“ค์€ ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ์ง€๊ธˆ์ฒ˜๋Ÿผ ๋˜‘๋˜‘ํ•˜๊ณ , ๊ทธ๊ฒƒ์€ ์•„์ง ๋˜ ๋‹ค๋ฅธ API๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ๋‹ค๊ณ  ํ•ด์„œ ๋ณ€ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ชฉํ‘œ๋Š” ์˜์–ด ์ด์™ธ์˜ ์–ธ์–ด๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด์˜ ์–‘์„ ๋Š˜๋ฆฌ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ๋™์ผํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ฐฉ๋ฒ•์„ ๋„์ž…ํ•˜๊ณ  ์ด์ „๊ณผ ๋™์ผํ•œ ์ง„์ž… ์žฅ๋ฒฝ์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋…ผ์Ÿ์„ ์œ„ํ•ด ๊ทธ๋ฆฌ๊ณ  ๊ณผํ•™์  ๋ชฉ์ ์„ ์œ„ํ•ด ์—ฌ๊ธฐ ์žˆ๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ์—๊ฒŒ ์œ ๋‹ˆ์ฝ”๋“œ ํ…์ŠคํŠธ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ€์žฅ ์ž˜ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•˜๋‚˜์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋ฅผ ์ง€์ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋‹จ์ˆœํ•จ์„ ์†์ž„์œผ๋กœ์จ: ์Šค์œ„ํ”„ํŠธ

  • String ๋Š” ์ž„์˜์˜ ์œ ๋‹ˆ์ฝ”๋“œ ํ…์ŠคํŠธ ๋ฒ„ํผ์ž…๋‹ˆ๋‹ค.
  • ๋ฐ˜๋ณต๋˜๋Š” Character ๋Š” ๋‹จ์ผ ์œ ๋‹ˆ์ฝ”๋“œ ์Šค์นผ๋ผ ๊ฐ’์ด ์•„๋‹ˆ๋ผ ํ™•์žฅ๋œ ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ์ž…๋‹ˆ๋‹ค. ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ ํ•œ ์— ๋Œ€ํ•œ ์ด ์˜ˆ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. let decomposed: Character = "\u{1112}\u{1161}\u{11AB}" // แ„’, แ…ก, แ†ซ
  • ์œ ๋‹ˆ์ฝ”๋“œ ์Šค์นผ๋ผ ๊ฐ’์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ด๋ฅผ ๋ฐ˜๋ณตํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ์œ ํ˜•์€ UnicodeScalar ์ž…๋‹ˆ๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  ์ •๋ง๋กœ ํ•„์š”ํ•˜๋‹ค๊ณ  ๋Š๋ผ๋ฉด UTF-8 ๋ฐ UTF-16 ์ฝ”๋“œ ๋‹จ์œ„๋ฅผ ๋ฐ˜๋ณตํ•˜์—ฌ UInt 8 ๋ฐ UInt 16 ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ C#์ด ์™„์ „ํ•œ Swift ์Šคํƒ€์ผ์ด ๋˜๋„๋ก ์ œ์•ˆํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋†€๋ผ์šด ์ผ์ด์ง€๋งŒ ๋˜ํ•œ ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์€ ๋ณ€๊ฒฝ๊ณผ ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ @Serentty ๊ฐ€ ์ง€์ ํ•œ ๋ชจ๋“  ์ด์œ ๋กœ Swift ์Šคํƒ€์ผ ์ด๋ฆ„ ์ง€์ •์„ ์ œ์•ˆํ•˜๊ณ  ํ…์ŠคํŠธ ๋ฌธ์ž์—ด์„ ๊ฒฐ๊ตญ Swift ์Šคํƒ€์ผ๋กœ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์„ ์—ด์–ด ๋‘ก๋‹ˆ๋‹ค.

Rune ๋ณด๋‹ค ๋” ๋‚˜์€ ์ด๋ฆ„: CodeUnit32 , UnicodeScalar , CodeUnit , UniScalar , UnicodeValue , UniValue , UnicodeScalarValue . ์ฒ˜์Œ ๋‘ ๊ฐœ๋Š” C#์˜ ๋ช…๋ช… ๊ทœ์น™์— ์ž˜ ๋งž์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. UnicodeScalar ๋Š” ๊ฐ๊ด€์ ์œผ๋กœ ๋” ๋‚˜์€ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ์ฝ”๋“œ ๋‹จ์œ„๋Š” ์œ ๋‹ˆ์ฝ”๋“œ ์šฉ์–ด๋กœ ์œ ๋‹ˆ์ฝ”๋“œ ์Šค์นผ๋ผ ๊ฐ’์„ ์ธ์ฝ”๋”ฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ CodeUnit32 ๋Š” UTF-32๋กœ ์ธ์ฝ”๋”ฉ๋œ ํ…์ŠคํŠธ ๋ฌธ์ž์—ด์˜ ์ฝ”๋“œ ๋‹จ์œ„๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๋Š” ๋ฐ˜๋ฉด UnicodeScalar ๋Š” ์ธ์ฝ”๋”ฉ์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํŽธ์ง‘: ์˜ˆ, System.Rune ๋ผ๋Š” ์ด๋ฆ„์ด ์ด๋ฏธ ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋“  ๊ฒƒ์€ "์ด๊ฒƒ์ด ๋ฐ˜์„ธ๊ธฐ๊ฐ€ ๋˜๊ธฐ ์ „์— ๋” ์ข‹๊ฒŒ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๋ฉด"์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

@ํŒŒ์ด๋ง›

๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ ๊ท€ํ•˜์˜ ์ „์ฒด ์ฃผ์žฅ์€ 'ํ˜ผ๋ž€์Šค๋Ÿฝ๊ณ  ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋ ‡๊ฒŒ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ณ  ๋‚˜์˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค'์ž…๋‹ˆ๋‹ค.

์•„๋‹ˆ, ๊ทธ๊ฒƒ์€ ์ „ํ˜€ ๋‚ด ์ฃผ์žฅ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‚ด๊ฐ€ ๊ฐ€์ง„ ์žฅ์• ๋ฅผ ๊ฐ€์ง€๊ณ  ์ตœ์„ ์„ ๋‹คํ•˜๊ณ  ์žˆ์ง€๋งŒ ์ด๊ฒƒ์€ ๋‚ด๊ฐ€ ์˜๋„ํ•œ ์˜์‚ฌ ์†Œํ†ต์ด ์•„๋‹™๋‹ˆ๋‹ค.

Google์—์„œ 'Unicode runes'๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ฉด ์ฝ”๋“œ ํฌ์ธํŠธ์™€ ๊ด€๋ จ๋œ ๋ชจ๋“  ๊ฒƒ์ด 2ํŽ˜์ด์ง€๊นŒ์ง€ ํ‘œ์‹œ๋˜์ง€ ์•Š๊ณ  ๊ทธ๋•Œ๋„ godoc/Nim ๋งํฌ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

Google์—์„œ '์œ ๋‹ˆ์ฝ”๋“œ ๋ฌธ์ž์—ด'์„ ๊ฒ€์ƒ‰ํ•˜๋ฉด .NET ๋ฌธ์ž์—ด์ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹๋„ ๊ตฌ์ฒด์ ์œผ๋กœ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ธ์ ‘ํ•œ ๊ฒƒ์„ ์ฐพ๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๋งค์šฐ ์—„๊ฒฉํ•œ ๋น„์œ ๋กœ ์ €๋Š” .NET๊ณผ Ada ๋ชจ๋‘์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•ฉ๋‹ˆ๋‹ค. string ๋Š” ๊ทธ๋“ค ์‚ฌ์ด์—์„œ ๋™์ผํ•˜์ง€ ์•Š์œผ๋ฉฐ ๊ฐ๊ฐ์— ๋Œ€ํ•ด ์•ฝ๊ฐ„์˜ ๋…์„œ๊ฐ€ ์ข‹์€ ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค.

์˜ค๋ฒ„๋กœ๋“œ๋œ ์ •์˜๋Š” ์–ธ์–ด์—์„œ ๋“œ๋ฌธ ์ผ์ด ์•„๋‹ˆ์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์ž˜ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋†€๋ž๊ฒ ์ง€๋งŒ "run"์—๋Š” ์ตœ์†Œ 179๊ฐœ์˜ ํ˜•์‹ ์ •์˜๊ฐ€ ์žˆ๊ณ  "take"์—๋Š” ์ตœ์†Œ 127๊ฐœ, "break"์—๋Š” ์ตœ์†Œ "123"์ด ์žˆ์Šต๋‹ˆ๋‹ค. [ ์ถœ์ฒ˜ ] ์‚ฌ๋žŒ๋“ค์€ ๋†€๋ผ์šธ ์ •๋„๋กœ ๋Šฅ๋ ฅ์ด ์žˆ์œผ๋ฉฐ ์—ฌ๊ธฐ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋ณต์žกํ•œ ๊ฒƒ์„ ์„ฑ๊ณต์ ์œผ๋กœ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์†Œํ•œ 2๊ฐœ์˜ ๊ณต์‹์ ์ธ ์ •์˜๊ฐ€ ์žˆ๋Š” "๋ฃฌ"์— ๋Œ€ํ•œ ์šฐ๋ ค๋Š” ์‚ฌ๋žŒ๋“ค์ด 50๋ฐฐ ์ด์ƒ์˜ ๊ณผ๋ถ€ํ•˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ผ ์ˆ˜ ์žˆ์„ ๋•Œ ๋ณด์ฆ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋”์šฑ์ด ์ด๊ฒƒ์€ ๊ฒ€์ƒ‰ ์—”์ง„ ๋™์ž‘์„ ์‹ฌํ•˜๊ฒŒ ์•…์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒ€์ƒ‰ ์—”์ง„์—์„œ๋Š” ๋ฌด์–ธ๊ฐ€์— ์—ฐ๊ฒฐ๋œ ํŽ˜์ด์ง€ ์ˆ˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฒฐ๊ณผ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. ๊ฐ ์ ‘๊ทผ ๋ฐฉ์‹์— ๋”ฐ๋ผ ๊ฐ€์ค‘์น˜๊ฐ€ ๋‹ค๋ฅด๊ฒŒ ์ ์šฉ๋˜๋Š” ๋‹ค๋ฅธ ์š”์†Œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. .NET Rune์€ ๋น„๊ต์  ์ตœ๊ทผ์˜ ๊ฐœ๋…์ด๋ฏ€๋กœ ์ด์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๋Š” ๋‚ด์šฉ์ด ํ›จ์”ฌ ์ค„์–ด๋“ค๊ณ  ์ดํ•ดํ•˜๋Š” ๋ฐ ๋” ๋งŽ์€ ํŽ˜์ด์ง€๊ฐ€ ์†Œ์š”๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ๋˜ํ•œ ์ž˜๋ชป๋œ ๊ฒ€์ƒ‰ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด ๊ฒ€์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋Œ€ํ•œ ์—ฐ๊ตฌ๋ฅผ ์ฐพ๊ณ  ์‹ถ๋‹ค๋ฉด ์ง€๋‚œ ๋ช‡ ๋…„ ๋™์•ˆ ์ƒˆ๋กœ์šด ๊ฒƒ์ด ๋‚˜์™”๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด Google์ด๋‚˜ DDG๋ฅผ ๊ฒ€์ƒ‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Semantic Scholar, Google Scholar ๋“ฑ์ด ๋” ๋‚˜์€ ์ถœ๋ฐœ์ ์ž…๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ .NET API์— ๋Œ€ํ•ด ์ดํ•ดํ•˜๋ ค๋ฉด ๋จผ์ € MSDocs๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ฆฌ/๊ณตํ•™ ์šฉ์–ด์ธ "๊ด€์„ฑ ๋ชจ๋ฉ˜ํŠธ"๊ฐ€ ์ด๋ฆ„์ด ๋ชจํ˜ธํ•˜๊ฑฐ๋‚˜ ์˜คํ•ด์˜ ์†Œ์ง€๊ฐ€ ์žˆ๋‹ค๊ณ  ๋ถˆํ‰ํ•˜๊ณ  ์ฒ˜์Œ ๋ช‡ ๊ถŒ์˜ ์ฑ…์—์„œ ๊ฐ€์žฅ ๋‚ฎ์€ ๋ฒˆํ˜ธ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ์ด์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฆ„์„ ๋ฐ”๊ฟ”์•ผ ํ•ฉ๋‹ˆ๋‹ค. Dewey Decimal Classification์„ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ๋Š” "๊ด€์„ฑ ๋ชจ๋ฉ˜ํŠธ"๋ผ๋Š” ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ถ„๋ช…ํžˆ ์ž˜๋ชป๋œ ๊ณณ์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜: ์ €๋Š” Go๋ฅผ ์‚ฌ์šฉํ•ด ์™”์œผ๋ฉฐ 4๋…„ ํ›„ ์ด ํ˜ธ๋ฅผ ์ฝ์„ ๋•Œ๊นŒ์ง€ ์ด๊ฒƒ์ด ์ž์†Œ์ธ ์ค„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ ์–ด๋„ ๋‚ด๊ฐ€ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” Go ๋ฌธ์„œ์™€ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ๋ฅผ ์‚ดํŽด๋ณด์•˜๊ณ  ๋‹น์‹ ์˜ ๋ง์— ๋™์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ rune ๊ฐ€ ๋ฌด์—‡์ธ์ง€์— ๋Œ€ํ•ด ๋งค์šฐ ๋ชจํ˜ธํ•˜๊ณ  ๋ถˆํ–‰ํ•˜๊ฒŒ๋„ rune ๊ฐ€ ์–ผ๋งˆ๋‚˜ ํฐ์ง€์กฐ์ฐจ ๋ชจํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” Ada๊ฐ€ ๋ฐ์ดํ„ฐ ์œ ํ˜• ์ œ์•ฝ ์กฐ๊ฑด์— ๋Œ€ํ•ด ๋˜‘๊ฐ™์ด ๋ชจํ˜ธํ•œ ๊ฒƒ์„ ๋ณด์•˜๊ณ  ๋ช‡ ๋…„ ํ›„์— ์Šค์Šค๋กœ๋ฅผ ๋ฌผ๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ๋ณด์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ชจํ˜ธํ•จ์ด ๋‚˜์ค‘์— ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” msdocs๊ฐ€ ๋งค์šฐ ์ƒ์„ธํ•˜๊ณ  ๊ฐ„๊ฒฐํ•œ ์„ค๋ช…์œผ๋กœ ํ›จ์”ฌ ๋” ๋‚˜์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค๊ณ  ๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์œ ๋‹ˆ์ฝ”๋“œ ์Šค์นผ๋ผ ๊ฐ’([ U+0000..U+D7FF ] ํฌํ•จ, ๋˜๋Š” [ U+E000..U+10FFFF ] ํฌํ•จ)์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

์ฆ‰, ์ฃผ์„์ด ๋‹ค์†Œ ๋ถ€์กฑํ•˜๊ณ  Rune ๊ฐ€ ์กด์žฌํ•˜๋Š” ์ด์œ ์™€ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒฝ์šฐ์— ๋Œ€ํ•œ ์„ค๋ช…์ด ์•ฝ๊ฐ„ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค (๋˜ํ•œ ์•ž์„œ ์–ธ๊ธ‰ ํ•œ ๋‹จ์ˆœํ™” ๋œ ์„ค๋ช…๋ณด๋‹ค ๋” ์ž์„ธํ•œ ์„ค๋ช…์„์œ„ํ•œ ์ ์ ˆํ•œ ์žฅ์†Œ) . ๊ฑฐ๊ธฐ์— ๋ช‡ ๊ฐ€์ง€ ๊ฐœ์„  ์‚ฌํ•ญ์„ ์ œ์‹œํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@์—๋ธŒ๋ฆฌ

๋…ผ์Ÿ๊ณผ ๊ณผํ•™์  ๋ชฉ์ ์„ ์œ„ํ•ด ์—ฌ๊ธฐ ์žˆ๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์œ ๋‹ˆ์ฝ”๋“œ ํ…์ŠคํŠธ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ€์žฅ ์ž˜ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•˜๋‚˜์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋ฅผ ์ง€์ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์˜๊ฒฌ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ ˆ๋Œ€์ ์œผ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. Swift๋Š” ํ™•์‹คํžˆ ์ตœ์‹  UNICODE๋ฅผ ๋” ์ž˜ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Ÿฌํ•œ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜๋Š” ๋™๋ฃŒ ๊ฒ€ํ† ์˜ ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ์—ฐ๊ตฌ์˜ ์ธ์šฉ ์—†์ด๋Š” ์ด๊ฒƒ์€ ๊ณผํ•™์  ์ฃผ์žฅ์ด ์•„๋‹™๋‹ˆ๋‹ค.

์ด์ œ C#์ด ์™„์ „ํ•œ Swift ์Šคํƒ€์ผ์ด ๋˜๋„๋ก ์ œ์•ˆํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋†€๋ผ์šด ์ผ์ด์ง€๋งŒ ๋˜ํ•œ ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์€ ๋ณ€๊ฒฝ๊ณผ ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ธฐ์กด ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๊นจ๋œจ๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ…์ŠคํŠธ ๋ฌธ์ž์—ด์„ ๊ฒฐ๊ตญ Swift ์Šคํƒ€์ผ๋กœ ๋ฐ”๊พธ๋ ค๋ฉด ์˜ต์…˜์„ ์—ด์–ด ๋‘์‹ญ์‹œ์˜ค.

๊ทธ๋ฆฌ๊ณ  ๊ธฐ์กด ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๊นจ๋œจ๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ, System.Rune์ด๋ผ๋Š” ์ด๋ฆ„์€ ์ด๋ฏธ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ชจ๋“  ๊ฒƒ์€ "์ด๊ฒƒ์ด ๋ฐ˜์„ธ๊ธฐ๊ฐ€ ๋˜๊ธฐ ์ „์— ๋” ์ข‹๊ฒŒ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๋ฉด"์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ธฐ์กด ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๊นจ๋œจ๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ธฐ์กด ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ Rune ๊ฐ€ ์ด๋ฏธ ์‚ฌ์šฉ ์ค‘์ธ .NET Core 3.0/3.1์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ๊ธฐ์กด ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์ œ์•ˆํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚˜์ค‘์— ๋Œ€์ƒ ๋Ÿฐํƒ€์ž„์—์„œ ๋‹ค๋ฅธ ์ด๋ฆ„?

๊ทธ๋ฆฌ๊ณ  ๊ธฐ์กด ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๊นจ๋œจ๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ๋‚˜๋Š” ์›์น™๊ณผ ์ด์ƒ์ฃผ์˜์˜ ๊ด€์ ์—์„œ ์ฃผ์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ๋ฌผ์˜ ํ˜„์‹ค์ด ๋งŽ์ด ์–ธ๊ธ‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์—๋Š” ์•ฝ๊ฐ„์˜ ๋‰˜์•™์Šค๊ฐ€ ์žˆ์ง€๋งŒ:

  • ๋ฌธ์ž์—ด์„ ์‚ฌ์šฉํ•˜์—ฌ Swift ์Šคํƒ€์ผ์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•ด์„œ ๋ฐ˜๋“œ์‹œ ์†Œํ”„ํŠธ์›จ์–ด๊ฐ€ ์ค‘๋‹จ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ด๋ฏธ ์กด์žฌํ•˜๋Š” String ์ธํ„ฐํŽ˜์ด์Šค ์œ„์— ๋” ๋งŽ์€ ์—ด๊ฑฐ ๋ฉ”์„œ๋“œ์™€ ์œ ํ˜•์„ ์ถ”๊ฐ€ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” System.Char ๋ฅผ ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ ์œ ํ˜•์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ๊ทธ์™€ ๊ฐ™์€ ๊ฒƒ์„ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.
  • System.Char ์™€ ๊ฐ™์€ ๊ธฐ์กด ์œ ํ˜• ์ด๋ฆ„์ด ๋‹ค๋ฅธ ์œ ํ˜•์œผ๋กœ ์šฉ๋„๊ฐ€ ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด ์˜ˆ, ์ด๋Š” ์—„์ฒญ๋‚œ ๋ณ€๊ฒฝ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์— ๋Œ€ํ•œ ๋ฌด์ฑ…์ž„ํ•œ ๋ณ€ํ™”. ๋‚˜๋Š” ๊ฑฐ๊ธฐ ๋‹น์‹ ๊ณผ ํ•จ๊ป˜ ์žˆ์–ด์š”.
  • SemVer๋กœ ๋งํ•˜๋Š” ๊ฐ€์ƒ์˜ .NET Core 4.0์€ ์›ํ•˜๋Š” ๋ชจ๋“  ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์™ธ์—๋Š” ๊ฐ€์ƒ 4.0๊นŒ์ง€์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ๊ทธ๋ ‡๊ฒŒ ๋ฌด์„ญ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. System.Rune ๋ฅผ System.UnicodeScalar ๋˜๋Š” ์ด๋ฆ„์ด ๋ฌด์—‡์ด๋“  ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์œ ํ˜• ๋ณ„์นญ์œผ๋กœ ๋ฐ”๊พธ์‹ญ์‹œ์˜ค. Rune ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด๋Š” ์‚ฌ์šฉ ์ค‘๋‹จ ๋ฉ”๋ชจ๋ฅผ ์ œ์™ธํ•˜๊ณ  ์ฐจ์ด๋ฅผ ๋Š๋ผ์ง€ ๋ชปํ•  ๊ฒƒ์ด๋ฉฐ ์ƒˆ ์†Œํ”„ํŠธ์›จ์–ด๋Š” ๋” ๋‚˜์€ ์ด๋ฆ„์˜ ์‹ค์ œ ์œ ํ˜•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐ€์ƒ์˜ 4.0 Rune ๋ฅผ ๋–จ์–ด๋œจ๋ฆฝ๋‹ˆ๋‹ค.
  • ์œ ์‚ฌํ•˜๊ฒŒ, System.Char ๋Š” System.CodeUnit16 ๋“ฑ์˜ ๋ณ„์นญ์œผ๋กœ ๋ฐ”๋€” ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Swift ์Šคํƒ€์ผ๋กœ ํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์‹ค์ƒ System.GraphemeCluster ๋ฅผ ๋ฏน์Šค์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋Ÿฌํ•œ ๋ชจ๋“  ์œ ํ˜•์— ๋Œ€ํ•ด ๋” ๋งŽ์€ ์ƒˆ ํ‚ค์›Œ๋“œ ๋ณ„์นญ์„ ๋„์ž…ํ•˜๋Š” ๊ฒƒ์€ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— ์ƒ๊ฐ์„์œ„ํ•œ ์Œ์‹์„ ๋–จ์–ด ๋œจ๋ฆฝ๋‹ˆ๋‹ค. ๋‚˜๋Š” System.Rune ๊ฐ€ ๋ชฉ์ ์— ๋งž์ง€ ์•Š๋Š” ์œ ํ˜• ์ด๋ฆ„์ด์ง€๋งŒ ์‹ค์ œ๋กœ ์ด์ „ ๋ช…๋ช… ์ƒํƒœ๋ฅผ ๋” ์•…ํ™”์‹œํ‚ค์ง€๋Š” ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์นจ๋‚ด ๋ชจ๋“  ์œ ๋‹ˆ์ฝ”๋“œ ์Šค์นผ๋ผ๋ฅผ ์ธ์ฝ”๋”ฉํ•  ์ˆ˜ ์žˆ๋Š” ์ ์ ˆํ•œ ์œ ํ˜•์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์€ ๋Œ€๋‹จํ•œ ์ผ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ณด๋‹ค ์ •ํ™•ํ•œ ์œ ๋‹ˆ์ฝ”๋“œ ์ฒ˜๋ฆฌ ๋ฐ ๋ช…๋ช… ์ถ”์„ธ๋ฅผ ์ „ํŒŒํ•  ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ๊ธฐํšŒ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ์žˆ๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ์ด ์ž์œ ๋กญ๊ฒŒ ์ œ์ณ๋†“์„ ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ์ž…๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” System.Text.Rune ๋ผ๋Š” ์ด๋ฆ„์€ ๋ฐฐ์†ก๋œ ์ œํ’ˆ์ด๋ฉฐ ์•ž์œผ๋กœ ์‚ฌ์šฉํ•  ์ œํ’ˆ์ž…๋‹ˆ๋‹ค. ์ด์ „์— Rune UnicodeScalar ๋ผ๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ์ƒ๋‹นํ•œ(๊ทธ๋ฆฌ๊ณ  ์—ด๋ค) ํ† ๋ก ์ด ์žˆ์—ˆ์ง€๋งŒ ๊ฒฐ๊ตญ Rune ๊ฐ€ ์ด๊ฒผ์Šต๋‹ˆ๋‹ค. ํŒ€์€ ํ˜„์žฌ๋กœ์„œ๋Š” ๋‹ค๋ฅธ ์ด๋ฆ„์„ ์„ ํƒํ•  ์ƒ๊ฐ์„ ํ•˜๊ณ  ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ์ด๊ฒƒ์— ์—ด์ •์ ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๊ณ  ์šฐ๋ฆฌ๋Š” ์—ฌ๊ธฐ์„œ ๋Œ€ํ™”๋ฅผ ๊ณ„์† ๋ชจ๋‹ˆํ„ฐ๋งํ•  ๊ฒƒ์ด์ง€๋งŒ, ๊ถ๊ทน์ ์œผ๋กœ ๋ช…๋ช… ๋ฌธ์ œ๋ฅผ ๊ณ„์†ํ•˜๋Š” ๋ฐ ์†Œ๋น„๋˜๋Š” ์—๋„ˆ์ง€๋Š” ์ด์ต์„ ๋‚ด์ง€ ๋ชปํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์„ค๋ช…์„ ์œ„ํ•ด ๋ฌธ์„œ์— ๋”ฐ๋ผ: .NET์˜ System.Text.Rune ์œ ํ˜•์€ ์œ ๋‹ˆ์ฝ”๋“œ ์Šค์นผ๋ผ ๊ฐ’๊ณผ ์ •ํ™•ํžˆ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ฑด์„ค์— ์˜ํ•ด ์‹œํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ Go์˜ rune ์œ ํ˜•๋ณด๋‹ค Swift์˜ UnicodeScalar ์œ ํ˜•๊ณผ ๋” ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

Rune ๋ฌธ์„œ์— ํ•ด๋‹น ์‚ฌ์šฉ ์‚ฌ๋ก€์™€ .NET์˜ ๋‹ค๋ฅธ ํ…์ŠคํŠธ ์ฒ˜๋ฆฌ API ๋ฐ ์œ ๋‹ˆ์ฝ”๋“œ์˜ ๊ฐœ๋…๊ณผ ๊ด€๋ จ๋œ ๋ฐฉ๋ฒ•์„ ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๋Š” ์„น์…˜์„ ์ถ”๊ฐ€ํ•˜๋ ค๋Š” ๋…ธ๋ ฅ์ด ์ง„ํ–‰ ์ค‘์ž…๋‹ˆ๋‹ค. ์ถ”์  ๋ฌธ์ œ๋Š” https://github.com/dotnet/docs/issues/15845์— ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ์ถ”์  ๋ฌธ์ œ์—์„œ ๊ฐœ๋… ๋ฌธ์„œ์˜ ํ˜„์žฌ ์ดˆ์•ˆ์œผ๋กœ ์—ฐ๊ฒฐ๋˜๋Š” ๋งํฌ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜์—๊ฒŒ UnicodeScalar ์˜ ์ฃผ์š” ๋‹จ์ ์€ ์œ ํ˜• ์ด๋ฆ„์˜ ๊ธธ์ด์™€ ์œ ํ˜•์˜ ๋ฐ์ดํ„ฐ ํฌ๊ธฐ ์‚ฌ์ด์— ํฐ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋„๋ฉ”์ธ์— ์•ฝ๊ฐ„์˜ ๊ณต๋ฐฑ์ด ์žˆ๋Š” int ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์‚ฌ์šฉ๋ฒ•์˜ ์žฅํ™ฉํ•จ์€ ๊ทน๋‹จ์ ์ž…๋‹ˆ๋‹ค.

foreach (UnicodeScalar unicodeScalar in name.EnumerateUnicodeScalars())
{
     // ... unicodeScalar contains 1 int
}

๋Œ€ $#$4$ char string (์ด์ƒ์ ์œผ๋กœ ์‚ฌ๋žŒ๋“ค์€ ๋ถ„ํ•  ๊ฐ’์„ ํฌํ•จํ•˜๋Š” ๋Œ€์‹  ์ „์ฒด ๊ฐ’์ด๋ฏ€๋กœ char ์ด์ƒ์˜ ์ƒˆ ์œ ํ˜•์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค)

foreach (char c in name)
{
     // ... c contains 1 ushort
}

Rune์€ ํ˜•์‹ ์ด๋ฆ„ ์žฅํ™ฉํ•จ์˜ ์ ˆ์ถฉ์•ˆ์ž…๋‹ˆ๋‹ค.

foreach (Rune rune in name.EnumerateRunes())
{
     // ... rune contains 1 int
}

@GrabYourPitchforks

์—ฌ๋ณด์„ธ์š”! ์†”์งํžˆ ๋งํ•ด์„œ, ๋‚ด๊ฐ€ ์ด ๋…ผ์Ÿ์— ํœ˜๋ง๋ฆฌ๊ฒŒ ๋œ ์ด์œ ๋Š” .NET ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๊ทธ ๋ฐฐ๊ฐ€ ํ•ญํ•ดํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์„ค๋“ํ•˜๋ ค๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋‹จ์ˆœํžˆ ๋‚ด ์˜๊ฒฌ์„ ํ‘œํ˜„ํ•˜๊ณ  ์‹ถ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์— ๋™์˜ํ•˜์ง€ ์•Š๋Š” ์ด ์Šค๋ ˆ๋“œ์˜ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค. C#์ด ์˜ค๋žซ๋™์•ˆ ๊ฐ€์ง€๊ณ  ์žˆ๋˜ ๊นจ์ง„ ๋ฌธ์ž ์œ ํ˜•๊ณผ ๋‹ฌ๋ฆฌ ๋งˆ์นจ๋‚ด _real_ ๋ฌธ์ž ์œ ํ˜•์„ ๊ฐ–๊ฒŒ ๋œ ๊ฒƒ์€ ํ›Œ๋ฅญํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉฐ ์ด๋ฆ„์€ ์™„์ „ํžˆ ๋ถ€์ฐจ์ ์ž…๋‹ˆ๋‹ค. ๊ฐ„๊ฒฐํ•จ๊ณผ ์ •ํ™•์„ฑ ์‚ฌ์ด์— ์—„์ฒญ๋‚œ ๊ท ํ˜•์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•˜๊ณ  CodePoint ์ •๋„์— ์ตœ์ ์˜ ์œ„์น˜๋ฅผ โ€‹โ€‹์ง€์ •ํ–ˆ์ง€๋งŒ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ๋™์˜ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋‹ค์‹œ ํ•œ ๋ฒˆ .NET์˜ ์œ ๋‹ˆ์ฝ”๋“œ ์ง€์›์„ ํ˜„๋Œ€ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•œ ๋ชจ๋“  ๊ฒƒ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค! ์ด๊ฒƒ์€ ์ „ ์„ธ๊ณ„์˜ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ํฐ ์ฐจ์ด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰

๊ด€๋ จ ๋ฌธ์ œ

jchannon picture jchannon  ยท  3์ฝ”๋ฉ˜ํŠธ

EgorBo picture EgorBo  ยท  3์ฝ”๋ฉ˜ํŠธ

Timovzl picture Timovzl  ยท  3์ฝ”๋ฉ˜ํŠธ

GitAntoinee picture GitAntoinee  ยท  3์ฝ”๋ฉ˜ํŠธ

bencz picture bencz  ยท  3์ฝ”๋ฉ˜ํŠธ