Runtime: إدخال System.Rune

تم إنشاؤها على ١٦ سبتمبر ٢٠١٧  ·  106تعليقات  ·  مصدر: dotnet/runtime

مستوحاة من المناقشة هنا:

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

أحد التحديات التي يواجهها .NET مع دعم Unicode الخاص به هو أنه متجذر في تصميم قديم في الوقت الحاضر. الطريقة التي نمثل بها الأحرف في .NET هي باستخدام System.Char وهي قيمة 16 بت ، وهي قيمة غير كافية لتمثيل قيم Unicode.

يحتاج مطورو .NET إلى التعرف على أزواج البدائل الغامضة:

https://msdn.microsoft.com/en-us/library/xcwwfbb8 (v = مقابل 110) .aspx

نادرًا ما يستخدم المطورون هذا الدعم ، غالبًا لأنهم ليسوا على دراية كافية بـ Unicode ، ناهيك عن ما يقدمه .NET لهم.

أقترح أن نقدم System.Rune مدعومًا بعدد صحيح 32 بت والذي يتوافق مع codePoint وأننا نظهر في C # النوع المكافئ rune ليكون اسمًا مستعارًا لهذا النوع.

سيصبح rune البديل المفضل لـ char ويعمل كأساس للتعامل الصحيح مع Unicode والسلسلة في .NET.

بالنسبة إلى سبب اسم رون ، يأتي الإلهام من Go:

https://blog.golang.org/strings

يقدم قسم "الرموز والأحرف والرونية" شرحًا ، وإصدار قصير هو:

"نقطة الرمز" هي نوع من الكلام الممتلئ ، لذا يقدم Go مصطلحًا أقصر للمفهوم: rune. يظهر المصطلح في المكتبات وشفرة المصدر ، ويعني تمامًا "نقطة الكود" ، مع إضافة واحدة مثيرة للاهتمام.

تحديث لدي الآن تنفيذ 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] بعض واجهات برمجة التطبيقات أعلاه تستغرق وقتًا طويلاً ، وتحتاج إلى أخذ طلسم.
  • [] الحاجة إلى تنفيذ IC مقارنة الأسرة
  • [] تحتاج RuneCount / RuneLen إلى أسماء أفضل ، راجع المستندات (ربما يجب أن تكون Utf8BytesNeeded؟)
  • [] أعلاه ، تشير واجهات برمجة التطبيقات "ustring" إلى واجهة برمجة تطبيقات UTF8 الخاصة بي ، وهذا في الحقيقة ليس جزءًا من واجهة برمجة التطبيقات ، ولكن يجب أن نفكر فيما إذا كانت هناك بوابة إلى System.String في بعضها ، أو إلى Utf8String.
api-needs-work area-System.Runtime up-for-grabs

التعليق الأكثر فائدة

قلتها في العدد الأصلي وسأقولها مرة أخرى. إن التخلي عما يقوله المعيار لأنك لا تحب العبارة سيؤدي إلى إرباك أكثر مما ستحل ، ونظرًا لوجود صفحة رموز رونية في Unicode ، فإن ذلك يربكها أكثر.

الاسم خاطئ.

ال 106 كومينتر

هل تتوقع أن يكون التمثيل في الذاكرة عبارة عن سلاسل من كائنات 32 بت ، أو أن يتم ترجمتها على الفور؟ وماذا عن الذاكرة المضاعفة إذا السابق؟ ما هو تأثير الأداء إذا كان الأخير؟

هل تسمية تقنية مرتبطة بـ Unicode بعد برنامج نصي يدعم Unicode (وتقنية لتحسين دعم المستوى النجمي بعد نص BMP ، في ذلك الوقت) فكرة جيدة؟

أعتقد أن الاقتراح (وربما يحتاج إلى توضيح أكثر) هو أن تمثيل السلاسل في الذاكرة لا يتغير على الإطلاق. لا يمثل النوع Rune سوى نقطة رمز 21 بت فردية مميزة (مخزنة على هيئة int 32 بت). من المحتمل أن تؤدي الطرق التي تشير إلى نقاط الرمز إلى إرجاع Rune بدلاً من ذلك. من المفترض أن هناك بعض الوظائف في string تتيح لك تعداد Rune .

أعتقد أن هناك نقطتين واضحتين نحتاج إلى الحصول على إجماع حول شيء مثل هذا:

  1. هل هناك قيمة كبيرة لإنشاء نوع Rune بدلاً من استخدام Int32 كما تفعل الطرق الحالية؟
  2. هل كلمة "رون" في الواقع اختيار جيد؟

للإجابة (1) ، أعتقد أننا بحاجة إلى وصف أكمل لكيفية الكشف عن Rune ، وما هي الطرق التي ستتلقىها وإعادتها ، وما إلى ذلك. ولتحديد ما إذا كان ذلك أفضل من الحصول على تلك التعاملات بـ Int32 بدلا من ذلك.

بالنسبة إلى (2) ، فأنا نفسي متردد بعض الشيء. كلمة "Rune" هي نوع من الكلمة الباطنية في اللغة الإنجليزية ، ولها بعض الدلالات غير العادية لاستخدامها في هذا السياق. هناك أيضًا نقطة يطرحها الآخرون: إنه يتعارض مع مفهوم Unicode آخر. عندما أقوم بالبحث عن "Unicode Rune" ، أحصل بشكل أساسي على نتائج لمجموعة Runic Unicode ، وعدد قليل فقط من وثائق لغة Go.

char نصف كلمة وكلمة كاملة أيضًا ؛ وعليك أن تفحص ما يحيط به لتحديد أيهما - مثل التيار يمثل نصف حرف أو حرف كامل.

ربما System.character حيث يكون دائمًا حرفًا كاملًا ...: نظارة شمسية:

char هو تمثيل رهيب بعض الشيء وحتى بالنسبة للغات الأسكي / اللاتينية فقط ؛ سيستمر انتشار الرموز التعبيرية ؛ هذا يعني أن char هو شيك وربما تحقق من النوع التالي char

@ نيك كرافر على تويتر

بينما utf8 هو ترميز ذو عرض متغير ؛ من النادر (على الإطلاق؟) أن يرغب المستخدم في التعامل مع أنصاف الأحرف ؛ كلا من utf8 و utf32.

نوع 32 بت سيعمل بشكل جيد للتعداد.

سيكون الأمر الأكثر صعوبة هو indexOf والطول وما إلى ذلك بالنسبة إلى منظور الأداء أو الذاكرة.

  1. مصفوفة البايت هي أفضل تمثيل لتنسيق معتم ؛ على سبيل المثال ، الاحتفاظ بالتنسيق في تنسيقه الأصلي أو تنسيقه النهائي (نقل الملف ، وضع الأسلاك ، إلخ)
  2. صفيف البايت هو أفضل تمثيل لعرض النطاق الترددي للذاكرة وحجم الذاكرة
  3. مصفوفة البايت متوافقة مع الموضع والفهرس والطول وما إلى ذلك من حيث البايت

ومع ذلك ، عندما تبدأ في الاهتمام بالشخصيات الفعلية ، والأحرف الكبيرة ، والانقسام على الأحرف ؛ فهم ماهية الحرف ، يصبح البايت عرضًا متغيرًا. Char لا يجعل ذلك أفضل حقًا ؛ يضاعف حجم أصغر الشخصيات ؛ يتضمن المزيد من الأحرف ، ولكن لا يزال العرض متغيرًا.

لهذا ، قد تكون القيمة 32 بت مفيدة جدًا من منظور كود المستخدم. ومع ذلك ، فإن لديها مشاكل مع الموضع والطول والعناصر الثانوية (indexOf ، إلخ)

أنا حريص جدًا على سلسلة ascii فقط وسلسلة utf8 "تنفيذ سلسلة مضغوطة" https://github.com/dotnet/coreclr/issues/7083؛ للمعالجة السريعة لسلاسل أسكي فقط

ومع ذلك ، معارضة كل شيء كنت أجادله هناك ... أتساءل كيف سيكون تمثيل 32 بت لـ utf8؟ موقف من شأنه أن تعيين الموقع ؛ سيكون البحث عن أحرف سريعًا كما هو الحال في ascii ، وتكون العناصر بأحجام أصلية وما إلى ذلك ، كيف يمكن أن تتراكم مقابل معالجة كل بايت أو حرف لتحديد حجمها؟

سيكون التحويل من وإلى أكثر تكلفة ؛ لذلك سيكون أكثر من تنسيق معالجة ؛ من تنسيق التخزين.

migueldeicaza كما فهمت ، فأنت تشير فقط إلى توسيع تنسيق حرف واحد من 16 بت حرف إلى 32 بت لذلك يتم تضمين جميع التمثيلات في القيمة ؛ بدلاً من احتمال وجود نصف قيمة - وليس بالضرورة التنسيق الداخلي.

ومع ذلك ، هناك بعض الأشياء التي يجب مراعاتها (مثل العلاقة بين الوظيفة وتكلفة البحث وما إلى ذلك)

جانبا: يتعامل Swift أيضًا في تنسيقات الأحرف الكاملة

يوفر Swift عدة طرق مختلفة للوصول إلى تمثيلات Unicode للسلاسل. يمكنك التكرار عبر السلسلة باستخدام عبارة for-in ، للوصول إلى قيم الأحرف الفردية الخاصة بها كمجموعات حروف حروف موسعة Unicode. تم وصف هذه العملية في العمل مع الشخصيات.

بدلاً من ذلك ، قم بالوصول إلى قيمة سلسلة في أحد التمثيلات الثلاثة الأخرى المتوافقة مع Unicode:

  • مجموعة من وحدات كود UTF-8 (يمكن الوصول إليها باستخدام الخاصية utf8 للسلسلة)
  • مجموعة من وحدات كود UTF-16 (يمكن الوصول إليها باستخدام الخاصية utf16 للسلسلة)
  • مجموعة من قيم Unicode 21 بت العددية ، مكافئة لنموذج ترميز UTF-32 للسلسلة (يمكن الوصول إليها باستخدام خاصية unicodeScalars للسلسلة)

قلتها في العدد الأصلي وسأقولها مرة أخرى. إن التخلي عما يقوله المعيار لأنك لا تحب العبارة سيؤدي إلى إرباك أكثر مما ستحل ، ونظرًا لوجود صفحة رموز رونية في Unicode ، فإن ذلك يربكها أكثر.

الاسم خاطئ.

تضمين التغريدة

سيوفر Rune العديد من العمليات التي تتوقعها اليوم على Char ، مثل ToLower [Invariant] و ToUpper [Invariant] و ToTitle و IsDigit و IsAlpha و IsGraphic و IsSymbol و IsControl.

بالإضافة إلى ذلك ، سيوفر أشياء مثل:

  • EncodeRune (لتشفير رون في مخزن بايت)
  • RuneUtf8Len (يُرجع عدد البايتات اللازمة لتشفير الرون في UTF8) ،
  • IsValid (ليست كل قيم Int32 صالحة)

وتتداخل مع السلسلة ، و Utf8string حسب الحاجة.

لقد قمت بنقل / تعديل دعم سلسلة Go إلى .NET ، وهي تقدم عرضًا لما سيبدو عليه هذا العالم (هذا بدون أي مساعدة في وقت التشغيل):

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

benaadams قال:

أتساءل كيف سيكون تمثيل 32 بت لـ utf8؟ موقف من شأنه أن تعيين الموقع ؛ سيكون البحث عن أحرف سريعًا كما هو الحال في ascii ، وتكون العناصر بأحجام أصلية وما إلى ذلك ، كيف يمكن أن تتراكم مقابل معالجة كل بايت أو حرف لتحديد حجمها؟

UTF8 هو تمثيل في الذاكرة ، سيستمر في الوجود وسيظل هو التمثيل (ونأمل أن يكون هذا هو الترميز الداخلي على المدى الطويل للسلاسل المستقبلية في .NET).

يمكنك فك تشفير سلاسل UTF16 الحالية (System.String) أو سلاسل UTF8 القادمة (Utf8String) ليس في Chars (لسبب توافق أنت وأنا على ذلك) ، ولكن في الأحرف الرونية.

بعض الأمثلة ، قم بتحويل سلسلة 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

لقد لاحظت للتو أنني لم أقم بتطبيق المفهرس ("Get me the n-th rune")

سرعة الوصول إلى Nth-rune في سلسلة هي وظيفة التخزين ، وليس من Rune نفسها. على سبيل المثال ، إذا كانت مساحة التخزين الخاصة بك هي UTF32 ، فلديك وصول مباشر إلى كل رون. هذا أكاديمي ، حيث لا يستخدمه أحد. يتطلب الوصول إلى العنصر N على UTF16 و UTF8 المسح المناسب للعناصر المكونة للسلسلة (بايت أو 16 بت ints) لتحديد الحد الصحيح. لا ينبغي الخلط بينه وبين String[int n] { get; } الذي يقوم فقط بإرجاع الحرف n ، بغض النظر عن صحته.

benaadams شخصية Swift هي مستوى أعلى من الرون. الأحرف في السرعة هي "مجموعات حروف حروف ممتدة" تتكون من واحد أو أكثر من الأحرف الرونية التي تنتج عند دمجها شخصية يمكن قراءتها من قبل الإنسان.

لذلك لا يحتوي حرف Swift على حجم 32 بت ثابت ، فهو متغير الطول (ويجب أن يكون لدينا أيضًا هذا البناء ، لكن هذا ينتمي إلى نوع بيانات مختلف). فيما يلي مثال من تلك الصفحة ، ولكن هذا يمتد أيضًا إلى ضبط صبغة الرموز التعبيرية:

هنا مثال. يمكن تمثيل الحرف é كرقم Unicode مفرد é (LATIN SMALL LETTER E WITH ACUTE ، أو U + 00E9). ومع ذلك ، يمكن أيضًا تمثيل نفس الحرف كزوج من الحجميات — حرف قياسي e (LATIN SMALL LETTER E ، أو U + 0065) ، متبوعًا بـ COMBINING ACUTE ACCENT القياسي (U + 0301). يتم تطبيق العدد القياسي لـ COMBINING ACUTE ACCENT بيانياً على العدد القياسي الذي يسبقه ، مما يحول الحرف e إلى é عندما يتم تقديمه بواسطة نظام عرض نصي مدرك لـ Unicode.

فقط بالنسبة لي grapheme ستكون الكلمة أكثر وصفًا للذات.

سنتان على الاسم ، نقلا مرة أخرى عن منشور Go على السلاسل مع التركيز:

" نقطة الكود " هي نوع من الكلام الممتلئ ، لذا يقدم Go مصطلحًا أقصر للمفهوم: rune. يظهر المصطلح في المكتبات وشفرة المصدر ، ويعني تمامًا "نقطة الكود" ، مع إضافة واحدة مثيرة للاهتمام.

أتفق 100٪ مع blowdart ، واصفا إياه بـ "رون" أمر محير وخاطئ. يشير رمز يونيكود القياسي ثلاث مرات فقط في الصفحة الأولى من فصل المقدمة ولكن المصطلح رون لا يظهر في أي مكان.

إذا كانت نقطة رمز ، فيجب تسمية نقطة الرمز ، بهذه البساطة.

إذا لم يظهر المصطلح rune في المعيار مطلقًا ، فيمكن أن يكون جيدًا ، المشكلة هي أنه يظهر عدة مرات في الفصل 8 ، فيما يتعلق بالرونية. إنه ليس مجرد خطأ ، إنه يخلط بين الأمر وآخر.

فقط بالنسبة لي grapheme ستكون الكلمة أكثر وصفًا للذات.

إذا كان هذا حوالي 32 بت من نقاط التعليمات البرمجية ، فإن المصطلح grapheme سيكون مربكًا لأن حرف الحروف هو شيء آخر مرة أخرى.

غالبًا ما أردت نوع بيانات رمز نقطة (ليس في فترة جيدة ، لأن ما عملت عليه قد تغير ، لكن منذ بضع سنوات كنت أرغب في ذلك كثيرًا وكتبت حلولًا جزئية متداخلة لأجزاء من تلك الحاجة و يمكن أن تفعله بمكتبة تم اختبارها جيدًا). لا أفهم سبب عدم تسمية هذا بشيء مثل CodePoint . معظم الناس الذين يدركون أنهم بحاجة إلى مثل هذا النوع من المرجح أن يفكروا من منظور نقاط الترميز على أي حال ، وليس من حيث الأحرف الرونية ؛ أو فيما يتعلق بنقاط الكود والرونية كأجزاء منفصلة من مهمتهم. لا تزال تستخدم ᚱᚢᚾᚪ ᛒᛇᚦ ᛥᛁᛚᛖ ᛒᚱᚣᚳᛖᚢ / rúna béoþ stille bryceu / الرونية. أحتاج فقط إلى استخدام الأحرف الرونية مرة واحدة سنويًا ، وبشكل عام باستخدام المخطوطات والحبر بدلاً من أي شيء رقمي ، ولكن هناك بالتأكيد أشخاص يتعاملون معها رقميًا أيضًا. (حتى مع بيانات القرن العشرين ، أعرف حالة من حيث يتم استخدامها في أرشفة بيانات حقبة الحرب العالمية الثانية).

لا يزال Grapheme أكثر تعقيدًا ، نظرًا لأن المرء غالبًا ما يريد الانتقال إلى ثماني بتات ← أحرف (يتم التعامل معها بشكل جيد بواسطة .NET بالفعل) ثم الأحرف ← نقاط الكود ، ثم نقاط الشفرة ← حروف الحروف.

وضع علامة على هذا باعتباره جاهزًا للاستيلاء عليه في الوقت الحالي.

الخطوات التالية : ما نبحث عنه هو: اقتراح رسمي يتضمن التعليقات الواردة أعلاه (التسمية الفعلية للنوع ، ومزايا استخدام هذا بدلاً من مجرد استخدام Int32).

لقد قمت بتحديث المشكلة ، مع كل من واجهة برمجة التطبيقات المقترحة والتنفيذ الأولي:

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

أما بالنسبة لتسمية النوع ، فإن الأمر يتعلق بالحصول على مكان حيث يمكنك البحث عن العمليات الصالحة على النوع ، بالإضافة إلى امتلاك قدرات خاصة بالنوع (انظر التنفيذ للحصول على بعض الأمثلة).

migueldeicaza قبل وضع علامة على أنه جاهز للمراجعة ، ما هي أفكارك بشأن المخاوف بشأن التسمية الفعلية للنوع ، هل تعتقد أنه ربما يكون CodePoint أفضل من حيث وصف هذا النوع؟

أعتقد أن حجة استخدام codepoint كاسم ضعيفة.

استخدامه فكرة سيئة ، على المدى الطويل ، يحتاج هذا إلى استبدال كل استخدام فردي لـ "char" في الكود الحالي - إذا كنا نأمل في الحصول على دعم Unicode المناسب.

أتمنى لو كان بإمكاننا استخدام كلمة "char" مثل Rust ، لكن للأسف ، أخذناها بالفعل ولدينا واحدة مكسورة.

الذهاب إلى اعتناق هذا الاسم هو سابقة جيدة.

أوافق على أن المصطلح code point ليس هو المصطلح الصحيح لاستخدامه هنا. على الأقل ، بناءً على معيار Unicode ، فإنه لا يتضمن قيمًا أعلى من 10FFFF (http://unicode.org/glossary/#code_point).

لا أحب المصطلح rune . أعتقد أن له استخدامًا حاليًا في Unicode وفي أي مكان آخر والذي لن يؤدي إلا إلى حدوث ارتباك بشكل عام. أعتقد أيضًا أن لديها فرصة جيدة للتعارض مع أنواع المستخدمين الحالية (خاصة بالنسبة لأشياء مثل Unity ، حيث قد يمثل "Rune" كائنًا معينًا للعبة).

ومع ذلك ، أحب فكرة النوع الذي يغطي النوع C ++ 11 char32_t ، فقط باسم مختلف.

هناك شيء يمكن قوله مقابل Char32 . إنه إلى حد كبير ، إنه مماثل لأسماء الأنواع لأنواع التكامل. يتحدث على المستوى المفاهيمي للشخصية ، بدلاً من مستوى نقطة الرمز. إنه ليس اسم البرنامج النصي.

نظرًا لأننا نتطلع إلى الحصول على nint ماذا عن nchar ؟

ستكون السابقة في قواعد البيانات nchar و nvarchar

حيث nchar هي شخصية شار / وطنية و nvarchar هي شخصية وطنية متفاوتة / متفاوتة ؛ ما هي أنواع الحقول التي يمكنك تخزين unicode عليها ، وكذلك بعض معايير ISO - لست متأكدًا من أي منها ، ربما SQL؟

ما هو استخدام يونيكود للرون؟ هذا خبر بالنسبة لي.

U + 16A0 إلى U + 16F8

يتم استخدامه للإشارة إلى صفحة رموز محددة في معيار Unicode. لقد تم طرحه عدة مرات في هذا الموضوع: http://unicode.org/charts/PDF/U16A0.pdf

آه رونيك ، لا رون.

اسم النسخ (System.Rune أو System.Char32) ليس بنفس أهمية التسمية التي سيتم عرضها في C #.

أولاً: نعم ، نعم ، وأكثر من هذا من فضلك. أحب هذه الفكرة (بصراحة ، لدي فكرة مماثلة لفترة طويلة الآن). في الواقع ، كنا نستخدم فئة سلسلة مخصصة وبنية شخصية في توافق Git الخاص بنا لاحقًا في Visual Studio لفترة من الوقت الآن (يتحدث Git في Utf-8 ويكون تحويل كل شيء بطيئًا جدًا).

فيما يتعلق بموضوع أسماء الطرق الثابتة ، هل يمكننا تجنب التسمية المختصرة التعسفية من فضلك؟ بالنظر إلى أن Char.IsPunctuation هي الطريقة الحالية ، هل يمكننا من فضلك عكس ذلك بـ Rune.IsPunctuation أو ما شابه؟

بافتراض (خطر دائمًا) قبول هذا ، هل يمكننا الحصول على rune أو c32 ، أو استبدال char بالكامل بتطبيق System.Rune ؟

أقترح unichar أو uchar على الرغم من أن uchar سيبدو كحرف غير موقع. بغض النظر عن اختيارك ، آمل أن نحصل على اسم مستعار محدد للغة له. أنا شخصياً معجب بشدة باستخدام الأسماء المستعارة للغة للأنواع البدائية.

أتفق أيضًا مع whoisj - سأفضل بالتأكيد أسماء الطرق الكاملة على الاختصارات / الاختصارات.

أتفق أيضًا مع whoisj - سأفضل بالتأكيد أسماء الطرق الكاملة على الاختصارات / الاختصارات.

تحتاج لغة IMO (والمكتبات الخاصة بها) إلى اختيار أسماء كاملة ومختصرة ، أو الانتقال إلى الاختصارات (مثل C مع strcmp ، و memcpy ، وما إلى ذلك)

أو فقط استبدل char بالكامل بتطبيق System.Rune ؟

سيكون هذا تغييرًا جذريًا لأسباب واضحة إلى حد ما.

سيكون هذا تغييرًا جذريًا لأسباب واضحة إلى حد ما.

كانت تعليقاتي في الغالب اللسان والخد ، والأمل. نوع 16 بت للحرف كان خطأ من البداية.

قبض جيد على التسمية ، سوف يصلح.

هناك تناقضات صغيرة أخرى في واجهة برمجة التطبيقات المقدمة ، وسوف نلقي نظرة على إصلاحها أيضًا.

تضمين التغريدة

آه رونيك ، لا رون.

الرونية هي الصفة ، رون الاسم. كل الشخصيات الرونية هي رونية.

_Runic_ هي الصفة _rune_ الاسم. كل الشخصيات الرونية هي رونية.

عادل كما يبدو ، يأتي "Cortana: حدد _'rune'_" مع:

حرف من الأبجدية الجرمانية القديمة ، مرتبط بالأبجدية الرومانية.

آه نعم ، عندما أرى كلمة "رون" ، أفكر على الفور في هذا الفصل الغامض عن المواصفات التي لم يقرأها أحد والتي تتحدث عن "رونك يونيكود بلوك".

أفكر في ذكريات الطفولة لقراءة تولكين.

ᛁ᛫ᚦᛁᛜᚲ᛫ᛟᚠ᛫ᚱᚢᚾᛖᛋ

نعم ، لا أفكر بالتحديد في المواصفات ، لكني أفكر في نوع الأحرف التي تشير إليها المواصفات.

أنت تقول rune وأفكر في السحر ، والخيال ، والألغاز الخفية ، واللغات القديمة ، وما إلى ذلك.

أنا سعيد لأنك لا ترى كلمة "رون" وفكرت على الفور "آه هذا يشير بوضوح إلى كتلة رونية يونيكود 7.0 التي ستقتصر قيمتها على تلك القيم الفريدة في النطاق 16A0..16F8".

أعلم أن تانر هو صوت واحد هنا ، وما زال البعض منكم يفكر "لكن ميغيل ، أرى كلمة" رون "وأفكر على الفور في نوع بيانات يمكن أن يحتوي فقط على 88 قيمة ممكنة". إذا كانت هذه مشكلة تعانين منها ، يا أخي / أختي ، لدي أخبار لك: لديك سمكة أكبر لتقليها.

لقد كنت أتابع هذا الموضوع لفترة من الوقت بمزيج من الإثارة والتردد لما يزيد قليلاً عن شهر. لقد حضرت مؤتمر التدويل واليونيكود الشهر الماضي ، ولم يتناول أي من العروض التقديمية .NET. هناك مشكلة في الإدراك مع .NET Framework ؛ واحدة ليست بالضرورة غير مكتسبة نظرًا لتاريخ ميزات العولمة الخاصة بها. ومع ذلك ، فأنا أحب البرمجة بلغة C # وأريد بالتأكيد رؤية ميزات جديدة تعزز مكانة .NET في مجتمع عالمي حقًا. أعتقد أن هذا الاقتراح هو خطوة جيدة في هذا الاتجاه لتبني المعايير التي يتوقعها مجتمع التدويل من البرمجيات.

لقد كان ترددي في الغالب حول الخلافات حول اسم النوع. في حين أنه من الصحيح أن مصممي Go اختاروا الاسم "rune" ، فإن هذا يمثل مشكلة للسبب المذكور أعلاه بشكل متكرر: هناك نقاط رمز تسمى الأحرف الرونية بشكل صحيح. من الصعب بالنسبة لي أن أتفق مع اقتراح يحاول التقيد عن كثب بمعيار محترم ، ثم إعادة تعريف المصطلحات التي تشكل جزءًا من المواصفات. علاوة على ذلك ، فإن الحجة القائلة بأن معظم المطورين يجهلون المصطلح خادعة نظرًا لأن المطورين الأكثر اهتمامًا باستخدام هذا النوع بشكل صحيح هم أكثر عرضة لفهم مواصفات Unicode ولديهم فكرة جيدة عن ماهية "rune" في الواقع. تخيل الغرابة التي يمكن أن توجد إذا قمت بخلط المصطلحات:

Rune.IsRune(new Rune('ᛁ')); // evaluates to true
Rune.IsRune(new Rune('I')); // evaluates to false

بالطبع ، سلكت الطريق السهل هنا ، النقد دون تقديم اسم جديد. أعتقد أن الاقتراح السابق لـ CodePoint هو الخيار الأكثر وصفًا ذاتيًا (ويظهر في وصف الإصدار الأصلي) ، ولكن char32 سيكون أكثر تكافؤًا مع الأنواع الأولية الحالية (على الرغم من أنني سأفعل تتردد في القول إن ليس كل نقطة رمز هي شخصية). إذا كان الهدف هو بناء دعم Unicode أفضل في .NET ، فأنا أؤيد هذا المسار تمامًا ، ولكن أفضل طريقة للقيام بذلك هي اتباع المواصفات.

ثلاثة اقتراحات:

  1. فئة Rune تفتقد "IsCombining" الحرج. بدون ذلك ، لا يمكننا التحويل من سلسلة من الأحرف الرونية (نقاط الرمز) إلى سلسلة من حروف الكتابة.
  1. أود أيضًا أن أحصل على فصل دراسي مماثل. حرف الحروف في هذا السياق هو في الحقيقة مجرد قائمة من واحد أو أكثر من الأحرف الرونية (نقاط الرمز) بحيث لا يتم دمج الأحرف الرونية الأولى ويتم دمج بقية الأحرف الرونية. حالة الاستخدام هي عندما يحتاج المطور للتعامل مع أجزاء من "الشخصيات المرئية". على سبيل المثال ، a + GRAVE عبارة عن حرفين رونيين يشكلان حرفًا واحدًا.

  2. في الشبكات ، غالبًا ما نحصل على جزء كبير من البايتات التي نحتاج إلى تحويلها إلى "سلسلة" مثل الكائن حيث قد لا تكون البايتات كاملة (على سبيل المثال ، يتم إخبارنا ببعض البايتات ، لكن البايت الأخير في تسلسل متعدد البايتات لم يكن " وصل ر تماما بعد). لا أرى أي طريقة واضحة لتحويل دفق البايت إلى دفق من الأحرف الرونية بحيث يُعتبر فقدان البايت الأخير من تسلسل متعدد البايت حالة طبيعية سيتم تصحيحها عندما نحصل على المجموعة التالية من البايتات.

وأخيرًا ، يرجى استخدام أسماء Unicode وتسميتها CodePoint. نعم ، يقوم اتحاد Unicode بعمل رهيب في شرح الفرق. لكن الحل هو إضافة وثائق واضحة وقابلة للاستخدام ؛ أي شيء آخر يربك المشكلة بدلاً من المساعدة في التوضيح.

لا أبدأ من أين أبدأ في طلب الدمج ، فلا Go أو Rust أو Swift على سطح مثل واجهة برمجة التطبيقات على Rune أو Character أو Unicode Scalar (أسمائهم مقابل System.Rune ). يرجى تقديم التنفيذ المقترح.

على مجموعات حروف الكتابة ، إنها فكرة جيدة ، يجب تتبعها بشكل مستقل عن System.Rune . لما تستحقه ، استخدم Swift Character لهذا الغرض ، ولكن Swift أيضًا ليس نموذجًا رائعًا للتعامل مع السلاسل.

يعد تحويل تدفقات البايت إلى رون مناسب مشكلة تنتمي إلى واجهة برمجة تطبيقات ذات مستوى أعلى. ومع ذلك ، يمكنك إلقاء نظرة على تطبيق ustring الخاص بي الذي يستخدم نفس الركيزة مثل تطبيق System.Rune الخاص بي لمعرفة كيفية تعيين هذه المخازن المؤقتة في سلاسل utf8:

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

الوثائق ، التي لم أقم بتحديثها حتى الآن منذ أن قدمت System.Rune في واجهة برمجة التطبيقات ، لكنها تغطيها:

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

بالنسبة للتسمية ، من الواضح أن Rust هو الأفضل بـ char ، لكننا أفسدنا ذلك. ثاني أفضل خيار هو Go with rune . أي شيء أكبر من أربعة أحرف سيكون مجرد مصدر إزعاج للأشخاص لفعل الشيء الصحيح.

أنا اسف؛ أعتقد أن CodePoint هو اسم جيد للغاية. إنه لا يحتاج إلى شرح ، ولا يُنسى ، ويكمل تلقائيًا مع c p .

سيكون IsCombining ضروريًا بالتأكيد ، ولكن أيضًا معرفة فئة الدمج وبمجرد أن يكون لدينا هذا IsCombining إلى حد كبير من السكر لأنه IsCombining => CombiningClass != 0 أو IsCombining => CombiningClass != CombiningClass.None . سوف تكون مجموعات Grapheme بالفعل خارجها مرة أخرى ، لكن نقطة البداية ستكون معرفة فئة التجميع للتجميع الافتراضي ، وإعادة الترتيب ، وما إلى ذلك.

CodePoint هو اسم رائع لنوع يتعلق بنقاط الكود ، والأربعة أحرف ليست حدًا علينا التعامل معه مع الأنواع الأخرى المستخدمة بكثرة ؛ string أكبر بنسبة 50٪ ولا يمنعنا من استخدامه بانتظام. أربعة أحرف منتقاة عشوائيًا سيكون اسمًا أفضل من تكرار خطأ Go.

نظرًا لأن uint غير متوافق مع CLS ، فلا يوجد مُنشئ متوافق مع CLS يغطي الطائرات النجمية. سيكون int ضروريًا أيضًا.

يمكن أن تؤدي التحويلات الضمنية ثنائية الاتجاه إلى حدوث أشياء سيئة مع زيادة الحمل ، لذلك ربما يجب أن يكون اتجاه واحد واضحًا. ليس من الواضح أيهما. من ناحية أخرى ، يكون uint / int أوسع من نقاط الكود لأن القيم التي تقل عن 0 أو أعلى من 10FFFF 16 ليست ذات مغزى ، ويسمح وجود هذا التحويل الضمني باستخدام أسرع لواجهات برمجة التطبيقات الحالية من أجل أعداد. من ناحية أخرى ، أرى الرغبة في الإرسال من رقم إلى نقطة رمز أكثر من العكس.

نظرًا لأن uint غير متوافق مع CLS ، فلا يوجد مُنشئ متوافق مع CLS يغطي الطائرات النجمية. سيكون ضروريًا أيضًا.

هذا ما لم يتم إدخال نوع جوهري جديد في اللغة المشتركة.

JonHanna - هل تقصد أن هؤلاء الصانعين الثلاثة:
عامل التشغيل الضمني الثابت العام (Rune rune) ؛
عامل التشغيل الضمني الثابت العام Rune (char ch) ؛
عامل التشغيل الضمني الثابت العام Rune (قيمة uint) ؛

يجب أن تكون "int" بدلاً من "uint". يغطي 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. قطعة من نوع الطباعة تحمل مثل هذا الرمز أو الحرف.

على الرغم من أن هذا يتعارض مع الحرف مقابل الرقم

الرسالة لها معنى أكثر دقة في unicode (والشبكة بشكل عام) من rune.

أعتقد ، إذا أردنا جعل هذا نوع حرف Unicode ، فإننا نحتاج إلى اتباع اصطلاحات تسمية Unicode ؛ وهو ما يعني _ "رمز نقطة" _.

كود بوينت . (1) أي قيمة في مساحة الترميز Unicode ؛ أي مدى الأعداد الصحيحة من 0 إلى 10FFFF16. (راجع التعريف D10 في القسم 3.4 ، الأحرف والتشفير .) لا يتم تعيين جميع نقاط الرمز للأحرف المشفرة. انظر نوع نقطة الرمز . (2) قيمة أو موضع لحرف ما في أي مجموعة أحرف مشفرة.

أو ربما نستسلم ونطلق على البطة لقب "البطة" ونشير إليها بأحرف Unicode (الملقب بـ uchar ).

لماذا لا تحل هذا فقط لاستخدام System.CodePoint بدلاً من ذلك؟
Imho هو أكثر ملاءمة من حيث المصطلحات من Unicode ، ويستخدمه أشخاص آخرون في عالم Java. لذا فبدلاً من استخدام مصطلح بمفردنا ، دعنا نلتزم بشروط Unicode. إنه منطقي أكثر وأكثر عالمية من حيث الأحرف العامة وتنفيذ السلاسل في .NET ، مع العلم أيضًا بحقيقة أن String في .NET هي مجموعة من char ، وهذه المجموعة من char تعتمد على Unicode.

أعلم ، لأنني عشت في عالم Java و .NET معًا.
وربما دعونا نبدأ في وضع مسودة تنفيذ حول هذا الموضوع.

يوجد حقًا مكونان من هذا وكلاهما مطلوب (CodeUnit في https://github.com/dotnet/corefxlab/issues/1799 بواسطةGrabYourPitchforks)

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> لضمان توفر واجهات برمجة التطبيقات النصية على أنواع النص ولكن ليس وحدات البايت الأولية.

CodePoint / uchar مهم للمعالجة المعقولة ؛ على سبيل المثال ، .IndexOf(❤) كـ 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 في تطبيقات النموذج الأولي الخاص بي للإشارة إلى قيمة عددية Unicode (قيم في النطاق U + 0000..U + 10FFFF ، بما في ذلك ؛ باستثناء نقاط الرمز البديل) و Utf8Char للإشارة إلى وحدة رمز UTF-8. يبدو أن الكثير من الناس يفضلون _Rune_ بدلاً من _UnicodeScalar_ لأنه أقل شذاً. لا أهتم كثيرًا ، لكنني سأشير إلى أن المصطلح "قيمة عددية Unicode" هو نفس المصطلح المستخدم في مواصفات Unicode . ؛)

يحتوي .NET Framework أيضًا على مفهوم "عنصر النص" ، وهو واحد أو أكثر من المقاييس التي عند دمجها تنشئ حرفًا حرفًا واحدًا غير قابل للتجزئة. مزيد من المعلومات حول هذا في MSDN . على وجه الخصوص ، عند تعداد سلسلة قد ترغب في تعدادها حسب وحدة الرمز ( Utf8Char أو Char ) ، أو القيمة العددية ( UnicodeScalar ) ، أو العنصر النصي ، اعتمادًا على سيناريو معين. من الناحية المثالية ، ندعم الأنواع الثلاثة عبر كل من String و Utf8String.

لم يتم الانتهاء من سطح واجهة برمجة التطبيقات للنموذج الأولي الخاص بنا وهو عرضة للتغيير السريع ، ولكن يمكنك رؤية بعض التفكير الحالي على 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.

قليلا خارج الموضوع:
هل يجب أن يكون "عنصر النص" هو التجزئة المحددة بواسطة "Grapheme Cluster Boundaries" في UAX dotnet / corefx # 29 ؟

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 Space (الإكمال التلقائي) نظرًا لأن هذا هو المصطلح الصحيح الأكثر وصفًا للذات ، آمل حقًا أن نحصل على ذلك.

ufcpp هذه نقطة جيدة. لا تتردد في فتح قضية جديدة لذلك. إذا لم نتمكن من تغيير السلوك لأسباب تتعلق بالتوافق ، فأنا أقترح أن نتجاهل هذا النوع وأن ننشئ عدادًا لغرافيًا متوافقًا مع المواصفات.

ubyte / uchar محير. يقرأون مثل unsigned char / unsigned byte نظرًا لاتفاقية تم إنشاؤها باستخدام ushort / uint / ulong . ربما char8 / u8char و char32 / u32char أكثر وضوحًا؟

على أي حال ، أعتقد أننا غير متحيزين بشأن ما إذا كانت وحدات كود UTF-8 ونقاط الكود هي:

  1. أنواع البيانات الأولية منخفضة المستوى في .NET - مثل byte ، int
  2. تنسيق بيانات للتحويل من / إلى العناصر الأولية الموجودة - مثل DateTime ، Guid

وبعد ذلك ، كيف نكشف واجهات برمجة التطبيقات المتعلقة بنقاط التشفير في ضوء هذا القرار؟

يعني الخيار 1 معالجة النص عبر أساسيات char8 و char16 و char32 (والمرافقة لـ u8string و u16string و u32string) مثل C ++ 17. ثم char32 كـ rune هو اسم سيء ، نظرًا لأن لدينا بالفعل char16 كـ char ونحتاج إلى اسم ثالث لـ char8 أيضًا.

الخيار 2 يعني أن البايت و int / uint "جيدان بدرجة كافية" لتخزين وحدات كود UTF ونقاط الكود. هذا يعني أن جميع السلاسل تظل UTF-16. CodePoint / rune يحل مشاكل الدلالات Code Point بدلاً من التمثيل الثنائي - ولا يُقصد به IO .

IMO UTF-8 / UTF-32 هي مجرد تنسيقات بيانات (الخيار 2). معاملتها كبيانات (بايت / عدد صحيح). CodePoint يشبه DateTime أو Guid (معرّف آخر *) من int بالنسبة لي - ليس نوعًا بدائيًا منخفض المستوى ، غير مدعوم بشكل مباشر في الإدخال / الإخراج (أي BinaryWriter) ، لا حاجة إلى الجوهر.

miyu النموذج الأولي الذي نحضره في corefxlab أقرب إلى الخيار 1. هناك أنواع بيانات محددة لتمثيل وحدات الكود ، وأنواع البيانات هذه مخصصة للتمثيل الداخلي للبيانات النصية ولا يمكن استخدامها لنقل البيانات النصية عبر السلك. (كما أشرت ، تعمل .NET بالفعل على هذا النحو اليوم: System.Char هي وحدة الكود لسلسلة UTF-16 ، ولكن لا يمكن إرسال System.Char عبر السلك.)

بالإضافة إلى ذلك ، هناك واجهات برمجة تطبيقات للتحويل بين byte[] / Span<byte> / وما إلى ذلك (هذا هو التمثيل الثنائي لجميع البيانات وهو مناسب لـ I / O) وأنواع بدائية مثل Utf8String / String / Guid / إلخ. بعض هذه الأمور أكثر مباشرة من غيرها. على سبيل المثال ، يمكننا الكشف عن خاصية ملائمة Utf8String.Bytes والتي تُرجع ReadOnlySpan<byte> لاستخدامها في i / o ، ويمكن أن يكون لجالب الخاصية O (1) تعقيد. لن نقدم مثل هذه الخاصية على النوع String ، على الرغم من أنه يمكنك تخيل وجود طريقة ملائمة String.ToUtf8Bytes() . وعلى الرغم من وجود خاصية Utf8String.Bytes ، فإن النوع الأولي من تعداد مثيل Utf8String مباشرة لن يكون byte . سيكون Utf8CodeUnit (الاسم TBD) أو UnicodeScalar ، أيهما نعتقد أنه أكثر منطقية لأنواع التطبيقات التي يرغب مطورو البرامج في إنشائها.

فكرة سخيفة خارج الحائط - ماذا عن wchar (_ char_ على مستوى العالم)؟ اليوم ، تستخدم معظم بيئات مترجم C و C ++ (خارج Windows) بالفعل wchar_t لتمثيل المكافئ الوظيفي لوحدة كود 32 بت. يعد Windows استثناءًا ملحوظًا ، حيث يتم تعريف wchar_t على أنه نوع 16 بت ، لكن المطورين الذين يستدعون p / على Windows اليوم يجب أن يكونوا مدركين بالفعل لاختلافات عرض البت بين .NET char والنمط C char .

النوع / الكلمة الرئيسية 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 #؟ من المؤكد أن عدم وجود واحدة للإصدار الأول أمر منطقي ، ولكن إذا كان هذا سيذهب في المستقبل إلى التعامل مع السلسلة ، فإن عدم وجود كلمة رئيسية ليس مخادعًا فحسب ، بل عدائيًا صريحًا تجاه اعتمادها.

تضمين التغريدة

لماذا لا تحصل على كلمة لغة C #؟

الكلمات الرئيسية الجديدة تكسر التغييرات بنسبة 100٪ من الوقت. بغض النظر عن الكلمة التي تختارها ، هناك شركة لديها نوع من هذا الاسم يتم استخدامه في كل مكان في مشروعهم. الخيار الوحيد المتاح لدينا هو الكلمات الرئيسية السياقية: var على سبيل المثال.

لدي مشاعر مختلطة حول استخدام كلمة رئيسية سياقية لهذا الغرض. الكلمات الرئيسية من النوع الحالي ( int ، string ، إلخ ...) لها ميزة ملموسة على اسم النوع الفعلي ( Int32 ، String ):

  • string : يشير إلى النوع System.String في التجميع الذي يحدده المحول البرمجي كـ corelib. هذا الاسم ليس له أي غموض مرتبط به.
  • String : المترجم ليس لديه أي فهم لهذا النوع. إنه مجرد نوع مثل أي نوع آخر ويخضع لنفس قواعد البحث مثل الأنواع التي تحددها. قد يكون معادلاً لـ string أو قد لا يكون كذلك.

بمجرد تقديم الكلمات الرئيسية السياقية هنا ، يمكن أن يكون rune إما:

  • النوع System.Rune داخل تجميع corelib
  • النوع rune الذي حددته قبل عامين عندما قرأت عن Go .

إن البحث عن rune غامض تمامًا مثل String ومن ثم لا أرى ميزة ثابتة لامتلاكه ككلمة رئيسية سياقية.

راجع للشغل: لهذا السبب يجب أن تستخدم string وليس String 😄

راجع للشغل: لهذا السبب يجب أن تستخدم string وليس String

أي 99٪ من السبب أعتقد أن الناس يريدون كلمة مفتاحية للغة. نسبة الـ 1٪ المتبقية هي مجرد "تبدو أفضل" 😏

رفض بسبب الكراهية الشديدة للكلمة الرئيسية "رون".

الكلمة الأفضل هي الصورة الرمزية ، لأنها تمثل بالفعل المفهوم العام للرمز العنصري في الطباعة.

الرون هو نوع معين من الحروف الرسومية التي يتم تعريفها بشكل مثير للسخرية بواسطة Unicode. إن الإشارة إلى "Go" باعتبارها حالة فنية سابقة أمر مثير للسخرية إلى حد ما. الفن السابق للرونية هو ما تمت كتابته في عام 150 بعد الميلاد وأحجار رونية فعلية. ليس ما يعتقده شخص ما في ريدموند أن الرون هو. إن محاولة إعادة تعريف المفاهيم الحالية مثل هذا أمر غير معتاد نظرًا لأن .NET عادة ما تحتوي على سطح API مصمم جيدًا. هذا استثناء نادر لتسمية API سيئة للغاية وأريد التعبير عن استيائي.

الكلمة الأفضل هي الصورة الرمزية ، لأنها تمثل بالفعل المفهوم العام للرمز العنصري في الطباعة.

المشكلة هي أن "Glyph" مصطلح مستخدم عند تقديم unicode إلى نص مرئي (من: utf8everywhere.org )

رسومي

شكل معين داخل خط. الخطوط عبارة عن مجموعات من الحروف الرسومية صممها مصمم النوع. إنها مسؤولية محرك تشكيل وتقديم النص لتحويل سلسلة من نقاط التعليمات البرمجية إلى سلسلة من الحروف الرسومية داخل الخط المحدد. قد تكون قواعد هذا التحويل معقدة وتعتمد على الإعدادات المحلية وتتعدى نطاق معيار Unicode.

إن الإشارة إلى "Go" باعتبارها حالة فنية سابقة أمر مثير للسخرية إلى حد ما.

استخدام المصطلح Rob Pike و Ken Thompson عند إنشاء Utf-8 https://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt

يعمل Rob Pike على Go now ، ولهذا السبب يستخدم المصطلح الأصلي.

الرون هو نوع معين من الحروف الرسومية التي يتم تعريفها بشكل مثير للسخرية بواسطة Unicode.

يتم تعريف Runic بواسطة Unicode ، بينما Rune ليس كذلك

يتم تعريف Runic بواسطة Unicode ، بينما Rune ليس كذلك

لا أعتقد أن هذا بيان دقيق ، أحدث مواصفات يونيكود (http://www.unicode.org/versions/Unicode11.0.0/UnicodeStandard-11.0.pdf) بها 37 نتيجة لـ "rune" (36 فقط صالحة ، الأخير جزء من كلمة أكبر) ويستخدم دائمًا للإشارة إلى الأحرف الفردية من الأبجدية الرونية.

لا أعتقد أن هذا بيان دقيق ، أحدث مواصفات unicode بها 37 نتيجة لـ "rune"

في النص الأساسي الذي يصف الدوافع ؛ ليس في أي اسم حرف أو اسم كتلة نصية (حيث الحرف الروني والروني)

في النص الأساسي الذي يصف الدوافع ؛ ليس في أي اسم حرف أو اسم كتلة نصية (حيث الحرف الروني والروني)

حسنًا ، عادل. ولكن بعد ذلك نعود إلى مشكلة أن مواصفات Unicode الحالية لا تحدد المصطلح "Rune" وعندما يتم استخدامه ، فهو مخصص للنص الإعلامي الذي يصف "الأحرف الرونية".

ما يعرف رسميًا ويستخدم لوصف الأشياء هو "Code Point" و "Code Unit".

  • حتى إذا استخدم المنشئ (المبدعون) الأصليون ، تاريخيًا ، مصطلح "Rune" ، فإن المواصفات الرسمية لا تفعل ذلك (وأتصور أن لديهم أسبابًا وجيهة لعدم استخدامه).

يجب أن يكون قصيرًا أو يصبح استخدامه قبيحًا

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. لا تتردد في ترك هذه المشكلة مفتوحة أو لحلها كما تراه مناسبًا.

لا أتوقع التأثير على أي شخص أو أن أكون قادرًا على تغيير أي شيء إلا للتسجيل فقط:

الكلمة الأفضل هي الصورة الرمزية ، لأنها تمثل بالفعل المفهوم العام للرمز العنصري في الطباعة.

المشكلة هي أن "Glyph" مصطلح مستخدم عند تقديم unicode إلى نص مرئي (من: utf8everywhere.org )

لا يدعم هذا الخط من التفكير الرون أيضًا ، لأن مصطلح "rune" كان مصطلحًا مستخدمًا لأكثر من ألف عام عبر التاريخ ، قبل وجود Unicode أو الترانزستورات أو Microsoft أو المصدر المفتوح بوقت طويل. إنه يشير على الأقل إلى أن البعض يطبق بشكل تعسفي معايير مختلفة على مقترحات مختلفة والتي من الواضح أنها غير متسقة ، لذلك ربما يتعلق الأمر أكثر بمن كان الأول أو الأعلى صوتًا بدلاً من الحجة الأكثر تماسكًا ، وماذا أعرف. أنا مجرد قادم متأخر أحاول فهم العملية ولكن هذا غير منطقي.

إن الإشارة إلى "Go" باعتبارها حالة فنية سابقة أمر مثير للسخرية إلى حد ما.

استخدام المصطلح Rob Pike و Ken Thompson عند إنشاء Utf-8 https://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt

يعمل Rob Pike على Go now ، ولهذا السبب يستخدم المصطلح الأصلي.

يتحدث كل من Go و Rob Pike عن القادمين الجدد نسبيًا إلى هذا الموضوع. في الواقع ، فإن رأيهم غير ذي صلة إلى حد ما من حيث تحديد ماهية الرون تاريخيًا وفي الأدب الشعبي والمجتمع. لم يدق روب أي أحجار رون بنفسه يدويًا ، لذلك لديه القليل من المؤهلات لتحديد ماهية الرون. أراهن أنه لا يستطيع حتى كتابة أو قراءة نص رون بنفسه ولكن هذا هو تخميني. في أحسن الأحوال ، يمكنه التقاط هذا المفهوم من خلال الترميز ، لكنه لا يستطيع أن يأتي ويقول أن الشخصية الصينية أو الكتابة العربية أو الهانغول أو الوجه المبتسم هي رون أو أي شيء آخر يمثل "رمز نقطة" أصبح الآن أيضًا طلسمًا ، أو شيء من هذا القبيل. يبدو تقريبًا أنه يدوس على المصطلح بطريقة غير محترمة ، انظر ، الآن يمكن أن يكون كل شيء رونًا ، مما يعني أن الأحرف الرونية ليست سوى مصطلح مكون من أربعة أحرف بدل للإشارة إلى شيء مقصور على فئة معينة في مجال تشفير النص.

الرون هو نوع معين من الحروف الرسومية التي يتم تعريفها بشكل مثير للسخرية بواسطة Unicode.

يتم تعريف Runic بواسطة Unicode ، بينما Rune ليس كذلك

ليس من المفترض أن يعيد Unicode تعريف ماهية الرونية أو الرونية. إذا فعلوا ذلك ، فإنهم يتجاوزون ولايتهم. ليس لديهم أي مصلحة في إخبار الجمهور ما هو الرون. في الواقع ، ليس لديهم عمل في تحديد أي لغة أو نظام شخصيات جديد على الإطلاق. لا يمكنهم فقط تخصيص كلمة كانت بالفعل عبارة عن مصطلح مثقل بشكل واضح منذ ألف عام ثم يركضون وهم يهتفون كما لو كانوا قد اخترعوا مفهومًا جديدًا. تتكون الكتابة الرونية من الأحرف الرونية فقط ، والرونية هي بالفعل مفهوم راسخ. إذا سألت شخصًا عشوائيًا في الشارع عن الرون فلن يفكر في Unicode.

بالإضافة إلى جميع المشاكل المذكورة أعلاه ، فإن الرون هو استعارة سيئة وهي أسوأ جزء. لا يوضح أي شيء. إنه يضيف مستوى آخر من الارتباك. يحتاج أي وافد جديد إلى الموضوع الآن إلى الخوض في جولة من شرح التوضيح والقراءة لأن الجميع يأتي مع سياق أن الرون هو نظام كتابة تاريخي مستخدم في ثقافات معينة. يجب أن يذهب التفسير إلى شيء مثل هذا: "الرون هو نقطة رمز Unicode". "ولكن لماذا لا نسميها نقطة الرمز؟" "حسنًا ، لأنها طويلة جدًا." ، أو "قرر شخص ما أنه يحب الرون". لذلك ، بشكل أساسي ، نظرًا لأن شخصًا ما يعتقد أن 9 أحرف أكبر من اللازم مقارنة بـ 4 (على الرغم من أن لديهم ميزة كاملة تلقائيًا مع Intellisense ولا يمكن مقارنتها بـ Java Kingdom Of Nouns) ، يتعين علينا الآن التعامل مع هذا الالتباس وشرح ذلك للآلاف من المطورين الذين قد يحتاجون إلى الاشتغال في Unicode. ما عليك سوى استخدام عبارة use لتقصير المصطلح إذا كنت تستخدمه كثيرًا في الكود.

ليس من الضروري أن تكون UnicodeCodePoint أيضًا ، يمكن أن تكون ببساطة CodePoint. هذا فريد بالفعل. هناك العديد من مصطلحات API التي تكون أطول من "CodePoint" لذا يجب أن يكون ذلك كافيًا. إذا كانت لا تزال طويلة جدًا ، فما عليك سوى استخدام عبارة استخدام مع بعض الاختصارات.

أتوقع أن يصبح هذا أحد أسئلة المقابلة المسدودة التي لا تضيف قيمة كبيرة أو لها أساس منطقي في أي شيء مفيد. على الأقل بالنسبة للاستعارة "معلم" ، بينما نتحدث عن موضوع الكلمات الرمزية المستخدمة في تطوير البرامج استنادًا إلى مفاهيم مشتقة من الحجر والصخور ، فإن معلمًا له معنى وصفي حقيقي. إنه ينقل على الفور مفهومًا يعرفه الجميع. آها ، علامة فارقة ، كما لو كنت في رحلة طويلة وتمر على درب. إنها استعارة لطيفة من العالم الحقيقي تساعد في الواقع على تصور شيء ما ويمكن أن تصبح لغة إدارية على الفور. لا يمكنني تخيل الأشخاص الذين يتحدثون عن الأحرف الرونية بهذه الطريقة ما لم يكونوا على دراية بالموضوع بشكل وثيق ، وعند هذه النقطة سيعرفون بالفعل أنه مجرد مصطلح للتحايل على نقطة الرمز.

الكلمة الأفضل هي الصورة الرمزية ، لأنها تمثل بالفعل المفهوم العام للرمز العنصري في الطباعة.

المشكلة هي أن "Glyph" مصطلح مستخدم عند تقديم unicode إلى نص مرئي (من: utf8everywhere.org)

لا يدعم هذا الخط من التفكير الرون أيضًا ، لأن مصطلح "rune" كان مصطلحًا مستخدمًا لأكثر من ألف عام عبر التاريخ ، قبل وجود Unicode أو الترانزستورات أو Microsoft أو المصدر المفتوح بوقت طويل.

كانت وجهة نظري أن كلمة "glyph" إشكالية لأنها استخدمت بالفعل كأحد المفاهيم في عرض النص ؛ إنه التمثيل الرسومي لذلك الحرف بخط معين. لذلك يمكن تمثيل الشخصية بالعديد من الصور الرمزية المختلفة.

... مرة أخرى مع benaadams الذي لديه عرض 10000 متر للأشياء والإجابة الصحيحة 😁

بصراحة ، علينا أن نتعايش مع القول المأثور القديم: "يمكنك أن تجعل بعض الناس سعداء طوال الوقت ، وكل الناس سعداء لبعض الوقت ؛ لكن لا يمكنك أن تجعل كل الناس سعداء جميعهم الوقت." هذا هو الوضع السابق إلى حد كبير.

سيجيل؟

Exit, pursued by a bear.

باعتباري شخصًا سيستخدم واجهة برمجة التطبيقات هذه على نطاق واسع ، فأنا أقوم بتصويت قوي لنقطة الرمز. مصطلحات Unicode محيرة بالفعل بدرجة كافية ، وهناك تناقضات كثيرة بالفعل. ستجعل حياتي أسهل كثيرًا إذا كان بإمكاني فقط أن أقول "نقطة الرمز" في كل مكان.

أنا مستلقية على السرير الآن. إذا استدرت بشكل جانبي ، فأنا أواجه لوحًا أبيض مسنودًا على الحائط. لأشهر ، كانت تلك السبورة موطنًا للعديد من الخربشات والرسوم البيانية بينما أحاول معرفة كيفية التعامل مع IDNs بكفاءة في C #. أنا أتعامل معها كأنها بقايا استدعيتها من أعماق الجحيم. إذا حاولت شرح المنطق الذي يصفه ، فلن أكون قادرًا على ذلك.

من فضلك ، لا تجعل حياتي أصعب. نقطة الرمز هي نقطة رمز. إنه ليس رونًا أو رسماً أو حرفًا أو حرفًا أو حتى رمزًا. لا يحتاج إلى تمثيل أي شيء ذي معنى للإنسان - يمكن أن يكون رمز تحكم. قد لا يمثل رمزًا مرئيًا ، كما يوحي الاسم "رون". إنها مجرد نقطة رمز.

هناك حجة أكثر واقعية وهي أن كلمة "rune" تتضمن تمثيل حرف حرف واحد ، وهو ما لا يحدث في كثير من الأحيان. إذا قمت بحساب عدد نقاط الشفرة وعدد حروف الكتابة ، فقد أحصل على رقمين مختلفين تمامًا. يمكن تمثيل نفس تسلسل حروف الكتابة من خلال سلسلتين متميزتين من نقاط الشفرة.

الكلمة الأفضل هي الصورة الرمزية ، لأنها تمثل بالفعل المفهوم العام للرمز العنصري في الطباعة.

هذا أسوأ. يمكن تمثيل نقطة رمز واحدة بواسطة صور رمزية متعددة ، ويمكن أن يمثل حرف رسومي واحد نقاط رمز متعددة. يمكن أن يختلف التعيين الدقيق حسب النظام والبرنامج والمحرف ...

كل هذه الكلمات لها معاني تقنية محددة للغاية. في حين أن الاختلافات قد تبدو غير مهمة في سياق هذا الاقتراح ، إلا أن لها عواقب حقيقية في أماكن أخرى ، لا سيما في لغات أخرى غير الإنجليزية.

كمثال على مدى صعوبة التعامل مع النص ، حتى في لغة شائعة مثل الألمانية:

  1. حوّل ß إلى أحرف كبيرة وستحصل على SS .
  2. حوله مرة أخرى إلى الأحرف الصغيرة وستحصل على ss .

مشاكل:

  • ما الذي يجب أن char.ToUpper('ß') ؟ (يجب أن تعيد حرفًا واحدًا.)
  • تمت إضافة نسخة كبيرة من ß والتي لا يستطيع هاتفي إدخالها في مربع النص هذا إلى Unicode 5.1. إذا حاولت لصقها ، أحصل على SS. الآن أصبحت التحويلات العلوية / السفلية أكثر غموضًا.
  • تغيير غلاف الخيط يغير طوله.
  • تغييرات الحالة ليست ثابتة أو قابلة للعكس.
  • لا يمكنك إجراء مقارنة غير حساسة لحالة الأحرف عن طريق تقليل أحرف كل سلسلة.

على الرغم من أن هذا ليس مثالًا مباشرًا لموقف تسبب فيه المصطلحات مشاكل ، إلا أنه يوضح كيف توجد أنواع من الحالات المتطورة التي لا نفكر فيها عادةً. إن إعطاء كل مصطلح معنى مميزًا ومتسقًا يساعد المبرمجين على توصيل هذه المشكلات. إذا طلبت من أحد زملائي في الفريق كتابة دالة لحساب حروف الحروف ، فإنهم يعرفون بالضبط ما الذي سيقومون بحسابه وكيفية القيام بذلك. إذا طلبت منهم حساب نقاط الرمز ، مرة أخرى ، فإنهم يعرفون بالضبط ما يجب عليهم فعله. هذه التعريفات مستقلة عن اللغات والتقنيات التي نستخدمها.

إذا طلبت من مطور JavaScript أن يحسب الأحرف الرونية ، فسوف ينظرون إلي وكأنني أمتلك ثلاثة رؤوس.

ويكيبيديا تقول

يعرّف Unicode مساحة رمز تبلغ 1،114،112 نقطة رمز في النطاق من 0hex إلى 10FFFFhex

يبدو أن رمز النقطة هو الاسم الرسمي. لقد قرأت هذا الموضوع ولم أجد حجة إجبارية لسبب كون نقطة الكود غير صحيحة.

أوافق على أن نقطة الرمز ليست هي المصطلح الصحيح لاستخدامه هنا. على الأقل ، بناءً على معيار Unicode ، فإنه لا يتضمن قيمًا أعلى من 10FFFF (http://unicode.org/glossary/#code_point).

ربما هذه الجملة خاطئة فقط؟ تقول "أي قيمة في مساحة الشفرة". لذلك من الواضح أنه يعني كل شيء بينما في نفس الوقت الحصول على عدد صحيح خاطئ.

أيضًا ، "rune" لها معنى حقيقي في العالم لا علاقة له بـ Unicode. في ألمانيا ، كلمة "Rune" لها دلالات نازية لأن الأحرف الرونية لها تاريخ "جرماني" يحب النازيون الإشارة إليه.

أجد "رون" اسم محير. هل يحب أي شخص هنا "الرون" حقًا أم أن الحجج المؤيدة لها تستند إلى صحتها. حدسيًا ، إنه اسم سيء حقًا.

ربما هذه الجملة خاطئة فقط؟ تقول "أي قيمة في مساحة الشفرة". لذلك من الواضح أنه يعني كل شيء بينما في نفس الوقت الحصول على عدد صحيح خاطئ.

هذه الجملة صحيحة. مساحة الرمز من U + 0000 إلى U + 10FFFF. يمكن من الناحية النظرية توسيع Unicode إلى ما بعد ذلك يومًا ما ، لكنه سيؤدي إلى كسر UTF-8 و UTF-16. سنحتاج ترميزات جديدة.

تحرير: في الواقع ، لا تقتبس لي من كسر UTF-16 ، لكنني متأكد من أنه سيتسبب في كسر UTF-8. لا يمكن أن يمثل UTF-8 بالتأكيد 0xFFFFFF (2 ^ 24 -1).

تحرير 2: للتوضيح ، تنص Unicode على أنه لا يمكن لنقاط الرمز أن تتجاوز U + 10FFFF. هذا لا يعني أن هناك حاليًا 0x110000 نقطة رمز - معظم نقاط الرمز هذه غير محددة.

تضمين التغريدة

هذا النوع الذي تم تسجيله حاليًا للرسالة الرئيسية ( System.Text.Rune ) يعيّن بشكل خاص جدًا "قيمة Unicode العددية" ( انظر المسرد ). ستطرح ctors للنوع استثناءً إذا حاولت إنشائه من القيم -1 ، 0xD800 ، أو 0x110000 ، لأن هذه ليست قيمًا عددية حسب مواصفات Unicode. إذا كنت تستخدم معلمة Rune كمدخلات إلى طريقتك ، فلن تضطر إلى إجراء أي تحقق من الصحة عليها. لقد ضمن نظام الكتابة بالفعل أنه تم إنشاؤه من قيمة عددية صالحة.

إعادة: تحويل الحالة ، كل واجهات برمجة تطبيقات تحويل الحالة في .NET Framework _ ما لم يُذكر خلاف ذلك _ استخدم تقنية تسمى طي الحالة البسيط. وفقًا لقواعد طي الحالة البسيطة ، لأي قيمة عددية للإدخال ، يُضمن أيضًا أن تكون كل من أشكال الأحرف الصغيرة والأحرف الكبيرة وحالة العنوان قيمة عددية واحدة بالضبط. (لا تحتوي بعض المدخلات ، مثل الأرقام من 0 إلى 9 أو رموز الترقيم ، على إدخالات في خريطة تحويل الحالة. في هذه الحالات ، تقوم عمليات مثل _ToUpper_ بإرجاع القيمة العددية للإدخال ببساطة.) بالإضافة إلى ذلك ، بموجب قواعد طي الحالة البسيطة إذا كان الإدخال في المستوى الأساسي متعدد اللغات (BMP) ، يجب أن يكون الإخراج أيضًا في BMP ؛ وإذا كان الإدخال في مستوى تكميلي ، يجب أن يكون الناتج أيضًا في مستوى إضافي.

هناك بعض العواقب لذلك. أولاً ، سيعود دائمًا Rune.ToUpper والأصدقاء قيمة _Rune_ واحدة (عددية). ثانيًا ، سيعيد الأصدقاء String.ToUpper دائمًا سلسلة بنفس طول الإدخال. هذا يعني أن السلسلة التي تحتوي على "ß" (eszett صغيرة) ، بعد عملية تحويل الحالة ، قد ينتهي بها الأمر تحتوي على "ß" (بدون تغيير) أو "" (majuscule eszett) ، اعتمادًا على الثقافة المستخدمة. لكنها _لن_ تحتوي على "SS" ، لأن هذا من شأنه أن يغير طول السلسلة ، وتقريبًا تستخدم جميع واجهات برمجة تطبيقات تحويل حالة .NET المكشوفة للجمهور قواعد بسيطة لطي الحالة. ثالثًا ، لا يتم _ضمان _ Utf8String.ToUpper والأصدقاء (الذين لم يتم تسجيل وصولهم) إرجاع قيمة تتطابق خاصية _Length_ مع خاصية _Length_ لقيمة الإدخال. (لا يمكن أن يتغير عدد وحدات رمز UTF-16 في سلسلة بعد طي الحالة البسيط ، ولكن يمكن أن يتغير عدد وحدات رمز UTF-8 في سلسلة. ويرجع ذلك إلى كيفية تشفير قيم BMP بواسطة UTF-16 و UTF- 8.)

هناك بعض واجهات برمجة التطبيقات .NET API التي تستخدم داخليًا قواعد طي الحالات المعقدة بدلاً من قواعد طي الحالة البسيطة. String.Equals String.Contains المماثلة قواعد طي الحالات المعقدة تحت String.IndexOf ، اعتمادًا على الثقافة. لذلك إذا تم تعيين ثقافتك على _de-DE_ ، فستتم مقارنة السلسلة المكونة من حرف واحد "ß" والسلسلة المكونة من حرفين "SS" على أنها متساوية إذا قمت بتمرير _CurrentCultureIgnoreCase_.

GrabYourPitchforks أنا أعترض بشكل أساسي على اختيار الاسم. كان مثال حالة الحالات هو مجرد التأكيد على مدى تعقيد Unicode (والنص بشكل عام). طالما أن هناك طريقة ما للتعامل مع التطبيع ، فأنا لا أهتم كثيرًا بكيفية عمل العمليات البسيطة ، حيث سأقوم بالتحويل إلى NFKD لكل شيء على أي حال لحالة الاستخدام الخاصة بي.

هذه الجملة صحيحة. مساحة الرمز من U + 0000 إلى U + 10FFFF. يمكن من الناحية النظرية توسيع Unicode إلى ما بعد ذلك يومًا ما ، لكنه سيؤدي إلى كسر UTF-8 و UTF-16. سنحتاج ترميزات جديدة.

لمجرد أن تكون صغيراً (أو ، إذا كان الأشخاص مهتمين): من الناحية النظرية ، تعمل خوارزمية UTF-8 لما يصل إلى 42 بت (البادئة بايت 0xFF و 7 بايت من حمولة 6 بت) ، وفي الأصل ، غطت المواصفات الأولى 31 بت كاملة مساحة بت لتلك الإصدارات القديمة من مجموعة الأحرف العالمية (UCS4) - ومع ذلك ، فإن المواصفات الحالية (RFC 3629 ، معيار Unicode ، الملحق D من ISO / IEC 10646) توافق جميعها على تقييدها بالنطاق الحالي لنقاط التشفير الصالحة (U + من 0000 إلى U + 10FFFF).

بالنسبة إلى UTF-16 ، يكون الوضع أكثر صعوبة. لكن يمكنهم حجز نقاط الرمز في مستوى علوي كـ "Escapes" لـ 32 بت أو أكثر. نظرًا لأن الطائرات من 3 إلى 13 غير محددة حاليًا ، فيمكنهم حجز طائرتين منهم على أنهما "طائرة بديلة منخفضة" و "طائرة بديلة عالية". ثم يتم تقسيم نقطة تشفير 32 بت إلى قيمتين 16 بت (واحدة في كل مستوى) ، ثم يتم تشفير كل قيمة باستخدام بدائلين "تقليديين" ، باستخدام 4 وحدات تشفير كل منها 16 بتة لتشفير نقطة تشفير 32 بت.

راجع للشغل ، AFAICS ، صرح اتحاد الكود الموحد علنًا أنه لن يقوم أبدًا بتخصيص نقاط كود أعلى من U + 10FFFF ، لذلك من الناحية العملية ، آمل أن أكون متقاعدًا لفترة طويلة قبل أن يحدث ذلك بالفعل. :غمزة:

هذا النوع كما هو مسجّل حاليًا في إتقان ( System.Text.Rune ) يعيّن بشكل خاص جدًا "قيمة Unicode العددية"

GrabYourPitchforks شكرا لهذا التوضيح. هذا يعني أن البنية لا تمثل نقطة رمز. لذلك سيكون هذا الاسم غير صحيح بالفعل.

أعتقد أن UnicodeScalar غامض للغاية كاسم ...

GrabYourPitchforks ، ما الذي تبقى لتفعله لهذه المشكلة؟

stephentoub لا توجد وظائف إضافية مخططة للصندوق الوارد Rune للنوع 3.0 ، لكن migueldeicaza كان لديه أفكار لتوسيع مدى هذا النوع ، بما في ذلك لأشياء مثل مجموعات حروف الكتابة. (أقرب شيء لدينا في الصندوق هو TextElementEnumerator ، وهو نوع قديم جدًا.) تم دمج بعض هذه الأفكار في هذا الموضوع ولكن لا يوجد شيء ملموس حتى الآن.

يمكننا ترك هذه المشكلة مفتوحة في حالة رغبة المجتمع في مناقشة السيناريوهات بشكل أكبر ، أو يمكننا توجيه الأشخاص لفتح مشكلات جديدة إذا كانوا يريدون تقديم اقتراحات محددة. TBH ليس لدي تفضيل قوي.

شكرا. نظرًا لأن Rune تم تقديمه بالفعل وتم الكشف عن واجهات برمجة التطبيقات الموضحة هنا (أو تقريبها) بالفعل ، فلنغلق هذا. يمكن معالجة الدعم الإضافي عبر قضايا منفصلة.

فهل هذا مستقر بشكل أساسي في هذه المرحلة؟ لأنه بكل صدق ، هذا الاسم المروع ، الذي لا يتماشى مع أي معلومات ستجدها عن Unicode من مصادر جيدة ودقيقة ، وله فارق بسيط يؤسف له في الإشارة إلى حرف رسومي بدلاً من شخصية غير مطبوعة ، سيذهب فقط إلى تفاقم الفهم المروع بالفعل لـ Unicode من قبل مبرمجك العادي.

أعلم أن هذا قد تم دمجه من خلال هذه النقطة ، لكني أريد فقط أن أشارك في الجزء Rune وبعض الناس يختلفون حول الاسم.

لقد واجهت لأول مرة Rune في الخطة 9 ، وكما شاهده الآخرون في Go وآخرون. عندما بدأ مُحرر msdocs في إدراج Rune كنت أعرف بالضبط ما كان عليه قبل القراءة.

في حالتين على الأقل ، الخطة 9 و Go ، لديك الأفراد المسؤولون عن UTF-8 باستخدام الاسم Rune . أعتقد أنه من الآمن أن نقول إنهم فكروا في هذه المخاوف بالفعل ولا يزالون يعتقدون أن Rune كان معقولًا. لم يعد Runic حقًا نظام كتابة مستخدمًا ، بخلاف بعض التقليديين. و Rune تعني حروف الكتابة في هذا النظام ، تمامًا كما تعني في الأساس حرف الحروف هنا (باستثناء حالات مثل أحرف التحكم.

أنا حقا أرى خطأ قليلا في التسمية. Runic هو نظام كتابة قديم أشك بشدة في أن مبرمجك العادي سوف يربكه ، وهناك بالفعل معيار واقعي عمره عدة عقود من Rune لـ "أحرف" Unicode المناسبة.

تضمين التغريدة

تمامًا مثل هذا يعني بشكل أساسي الحرف هنا (إلا في حالات مثل أحرف التحكم.

هذا ببساطة غير صحيح. يحتوي Unicode على عدد كبير من نقاط الشفرة المركبة مسبقًا والتي تمثل حروفًا متعددة (بشكل عام مجموعات الحروف والتشكيل) ، وتستخدم هذه بشكل شائع لكتابة لغات مثل الفرنسية والإسبانية ، وستستخدم جميع النصوص المحوسبة في هذه اللغات إلى حد كبير هذه الرموز نقاط.

على العكس من ذلك ، حتى عندما تمثل نقطة رمز واحدة حرفًا حرفًا واحدًا ، فمن الشائع جدًا أن يتم دمجها في مجموعة _grapheme_ ، وهو أمر ضروري للتعامل الصحيح مع النص في معظم اللغات الهندية. لذلك ، غالبًا ما يتوافق الحرف الفردي كما يراه المستخدم عند التنقل باستخدام مفاتيح الأسهم مع نقاط رمز متعددة في التسلسل. لذلك ، لا يمكن أن تكون هناك مراسلات سهلة بين نقاط الرمز وأي من مجموعات حروف الكتابة أو حروف الكتابة. حتى "الشخصية" من المحتمل أن تكون اسمًا أفضل ، مع الأخذ في الاعتبار أن المبرمجين معتادون على التفكير في الشخصيات غريبة وغريبة في هذه المرحلة ، بينما تعطي كلمة "رون" الانطباع بأن مشكلة معرفة حدود الشخصية التي يتصورها المستخدم قد تم حلها للمبرمج بالفعل عندما لم يكن في الواقع.

عندما بدأ مُحرر msdocs في إدراج Rune ، كنت أعرف بالضبط ما كان عليه قبل القراءة.

حقيقة أنك اعتقدت أن اسم رون وصف حروف اللغة بشكل جيد هو دليل جيد جدًا على المشكلة التي لدي هنا: الاسم "رون" يعطي المبرمجين إحساسًا زائفًا بالأمان من خلال تسهيل افتراض وجود مثل هذه المراسلات.

في حالتين على الأقل ، الخطة 9 و Go ، لديك الأفراد المسؤولون عن UTF-8 باستخدام الاسم Rune .

بقدر الاحترام الذي أكنه لكين طومسون وروب بايك ، كان عملهم هنا في الأساس مجرد ابتكار مخطط ذكي للغاية لترميز سلسلة من الأعداد الصحيحة متغيرة الطول. إنهم ليسوا خبراء في Unicode ككل ، وأنا أختلف معهم بشدة في هذه المسألة. أعترف أنني لست خبيرًا في Unicode أيضًا ، لكنني لا أعتقد أن مناشدة السلطة هنا قوية كما قد تبدو.

وهناك بالفعل معيار واقعي عمره عدة عقود من Rune لـ "أحرف" Unicode المناسبة.

"قياسي" تقول؟ لقد كان هذان الشخصان في الغالب هما اللذان يدفعان الاسم ، وبعض لغات البرمجة الثانوية مثل Nim التي تتبناها من Go. وبالطبع يجب أن أكرر مرة أخرى أن نقطة الرمز لا تمثل "حرف Unicode مناسبًا" سواء كان ذلك بمعنى الاختيار ، أو حركة مفتاح السهم ، أو حروف الكتابة ، أو مجموعات حروف الكتابة.

... تعني في الأساس الحرف هنا ...

نعم ، لأنها ليست بالضبط ولكنها قريبة بدرجة كافية. الحروف الهجائية ، على الأقل كما تم تعريفها في علم اللغة ، هي المكونات الإملائية التي تشكل نظام الكتابة وتستخدم للتعبير عن الصوتيات. هذه ليست 1: 1 شيء. في المقاطع الصوتية ومقاطع الشعارات ، يمكن أن يمثل حرف حرف واحد أصواتًا متعددة ، عادةً ما يكون زوجًا ساكنًا وحرفًا متحركًا. على العكس من ذلك ، غالبًا ما تحتوي اللغات الأبجدية على حالات متعددة الحروف الهجائية التي تمثل صوتًا واحدًا ، مثل "th" في اللغة الإنجليزية كونها مسؤولة عن الأخلاق القديمة والشوكة ، اعتمادًا على الكلمة المحددة. ثم لا يمكنك حتى العثور على اتفاق عبر اللغات حول ما إذا كان حرف مثل "á" هو حرف فريد خاص به ، أو "a" بلكنة. لا يمكننا حتى إثبات الاتساق في اللغات التي يزيد عمرها عن آلاف السنين. لن يكون لدينا إضافة متسقة تمامًا علاوة على ذلك ، وهذا هو ترميز هؤلاء.

نظرًا لأنك تدافع عن دلالات صارمة للغاية ، فإن ما تسميه UNICODE "مجموعة حروف الكتابة" غالبًا ما يكون في علم اللغة مجرد حرف حرف واحد. هل هذا غير صالح UNICODE؟ لا ، هل هذا يعني أن UNICODE تحتاج إلى إعادة تسميتها؟ لا لماذا؟ لأن السياق. الحقول لها لغتها الخاصة ، وطالما أنه لا يوجد خلط في حقل واحد ، فهذه ليست مشكلة.

لا أرى الاسم على أنه صفقة كبيرة جدًا. إن برنامج Msdocs واضحًا بشأن ما هو Rune في الملخص. إذا لم يقرأ الناس المستندات فهذه مشكلتهم الخاصة. لا يتفاعل الناس بشدة مع "ستريم" ويقولون هراء مثل "أوه ولكن ماذا لو اعتقد الناس أنه نهر صغير ، لأن هذا بالفعل يحمل نفس الاسم!" رقم.

SerenttyEntomy قد يكون كلاكما مهتمًا أيضًا بفئة StringInfo ، والتي تكشف عن مفهوم Unicode الفعلي "مجموعات حروف الحروف الموسعة". النوع StringInfo قديم نوعًا ما ونتيجة لذلك يتم تنفيذ إصدار قديم جدًا من معيار Unicode ، ولكن هناك عمل نشط لتحديثه ليكون متوافقًا مع UAX # 29، Sec.

نعم ، لأنها ليست بالضبط ولكنها قريبة بدرجة كافية.

أعتقد أن مسألة التمثيلات المركبة مقابل التمثيلات المتحللة تجعل هذا غير صحيح. إذا كنا ننتقل إلى التعريف اللغوي للحرف هنا بدلاً من أي نوع من التعريف المرتبط بالحوسبة ، فإن و هما نفس التسلسل الدقيق لمخططات الحروف (ثلاثة هانغول جامو تمثل المقطع _han_ مثل مقاطع HAN) ، و ومع ذلك ، فإن الأولى هي نقطة رمز واحدة فقط بينما الثانية عبارة عن سلسلة من ثلاثة.

الحقول لها لغتها الخاصة ، وطالما أنه لا يوجد خلط في حقل واحد ، فهذه ليست مشكلة.

هذه هي وجهة نظري بالضبط. Unicode هو نظام معقد حقًا له مصطلحاته الخاصة ، فلماذا نحاول فرض نوع من المصطلح "البديهي" نصف المخبوز عليه عندما لا يصطف بهذه الدقة؟ نقاط الرمز هي نقاط رمز. ليس لديهم مثيل لغوي ، ومحاولة أن تكون بديهية بينما 75٪ فقط دقيقة هي وصفة لنفس النوع من الكارثة التي لا يزال C # يحاول التعافي منها.

نظرًا لأنك تدافع عن دلالات صارمة للغاية ، فإن ما تسميه UNICODE "مجموعة حروف الكتابة" غالبًا ما يكون في علم اللغة مجرد حرف حرف واحد.

في المعيار ، يُسمح للكتلة بأن تشتمل على حرف حرف واحد فقط. لا حرج في هذا هنا. A _cluster_ هي وحدة لاختيار النص وحركة المؤشر.

لا أرى الاسم على أنه صفقة كبيرة جدًا. إن برنامج Msdocs واضحًا بشأن ماهية Rune في الملخص. إذا لم يقرأ الناس المستندات فهذه مشكلتهم الخاصة.

هذه هي حجة "يحتاج المبرمجون إلى أن يكونوا أكثر ذكاء" والتي تبرز مرارًا وتكرارًا للدفاع عن قرارات التصميم السيئة. إذا احتاج المبرمجون إلى قراءة الوثائق وتعلم أن الرون هو نقطة رمز Unicode على أي حال ، فما الفائدة من تسميته باسم "بديهي" في المقام الأول؟ يبدو أن الحجة هنا هي أن "نقطة الكود" محيرة ، لذلك من المنطقي اختيار اسم أكثر سهولة ، ولكن عند مواجهة مشكلة الاسم المضلل ، فإن الدفاع هو أن المبرمجين يجب أن يعرفوا ما هي نقطة الرمز على أي حال من قراءة الوثائق. إذا كان الأمر كذلك ، فلماذا لا تتصل فقط بالنوع CodePoint وتجعل من السهل على المبرمجين البحث والتعرف على المزيد؟ كل هذا يضع جانباً مشكلة أن وثائق .NET مروعة جدًا فيما يتعلق بـ Unicode في المقام الأول ، وتعامل الأزواج البديلة على أنها فكرة متأخرة في عالم من "أحرف Unicode ذات 16 بت".

هذه هي حجة "يحتاج المبرمجون إلى أن يكونوا أكثر ذكاء" والتي تبرز مرارًا وتكرارًا للدفاع عن قرارات التصميم السيئة.

أنا لم أقل هذا قط.

يبدو أن الحجة هنا هي أن "نقطة الرمز" محيرة

انا لم اقل هذا ابدا

لا يتفاعل الناس بشدة مع "ستريم" ويقولون هراء مثل "أوه ولكن ماذا لو اعتقد الناس أنه نهر صغير ، لأن هذا بالفعل يحمل نفس الاسم!" رقم.

أنا أقول إن المبرمجين أذكياء بما يكفي لعدم الاعتقاد بأن Rune هو على وجه التحديد رون روني ، إلى حد كبير بالطريقة نفسها التي يعرفون فيها أن Stream ليس نهرًا صغيرًا.

اسمحوا لي أن أكرر هذا

أنا أقول أن المبرمجين أذكياء بما يكفي لمعرفة ذلك. أنت تضع الكلمات في فمي.

لا أرى الاسم على أنه صفقة كبيرة جدًا. إن برنامج Msdocs واضحًا بشأن ماهية Rune في الملخص. إذا لم يقرأ الناس المستندات فهذه مشكلتهم الخاصة.

هذا ما أشير إليه هنا. تستند الحجة لصالح الاسم "رون" على الحدس والاتصال الحدسي بمفهوم حرف الحروف. أنت نفسك كنت تجادل في أن الاثنين اصطفما بشكل وثيق بما فيه الكفاية بحيث لم تكن مشكلة. عندما أشرت إلى جميع الطرق التي كان فيها هذا الحدس خاطئًا وأن المراسلات يمكن أن تكون سيئة للغاية ، كان ردك في الأساس أنه لا يهم لأن المبرمجين كانوا بحاجة إلى قراءة الوثائق على أي حال. هذا ما أعنيه بعبارة "يحتاج المبرمجون إلى أن يكونوا أكثر ذكاءً." التوثيق ليس عذرا لتضليل الأسماء عندما لا يكون هناك سبب موروث لها.

أنا أقول إن المبرمجين أذكياء بما يكفي لعدم الاعتقاد بأن Rune هو على وجه التحديد رون روني ، إلى حد كبير بالطريقة نفسها التي يعرفون فيها أن Stream ليس نهرًا صغيرًا.

حجتي هنا ليست أن الناس سوف يخلطون بينها وبين الأحرف الرونية. حجتي هي أن الناس سوف يخلطون بينه وبين مجموعات الحروف الرسومية ، والأحرف ، والحروف ، والتي على الرغم من إصراركم ترتبط جميعها بشكل سيء للغاية بنقاط الكود.

أنا أقول أن المبرمجين أذكياء بما يكفي لمعرفة ذلك. أنت تضع الكلمات في فمي.

ذكي بما يكفي لمعرفة أنهم ليسوا رونية جرمانية فعلية ، بالتأكيد. ولكن لمعرفة أنها ليست حروفًا رمزية ، أو حروفًا مكتوبة ، أو مجموعات من حروف الكتابة؟ تجربتي الفعلية مع جودة معالجة معظم البرامج لـ Unicode تقول لا.

إذا لم يقرأ الناس المستندات فهذه مشكلتهم الخاصة.

نعم ، وأنا أؤيد هذا. ليس بسبب نقص في الذكاء ، ولكن بسبب الميل نحو افتراضات متسرعة.

إذا افترض أحد المبرمجين أن String يعني قطعة حبل قوية ورقيقة مصنوعة من لف الخيوط ، لأنه ، نعم ، هذا يعني ذلك ، لا يعتبر ذلك مشكلة بالاسم String .

إذا افترض أحد المبرمجين أن Char يعني مادة متفحمة مثل الفحم ، أو نوع معين من سمك السلمون المرقط ، فلا يعتبر ذلك مشكلة بالاسم Char .

إذا افترض أحد المبرمجين أن character يعني تصوير مجموعة من السمات العقلية والأخلاقية المستخدمة في سرد ​​القصص ، فلا يعتبر ذلك مشكلة بالاسم character .

لاحظ أن هذه كلها أمور نصية / لغوية. كلهم لديهم معاني أخرى. ومع ذلك ، تأقلم المبرمجون بشكل جيد. أصبحت هذه المصطلحات معايير واقعية ، بسبب اتفاقية راسخة في هذا المجال: لغتنا. هناك سابقة ثابتة أن المبرمجين _ هم أذكياء بما يكفي لمتابعة هذا الأمر.

أنت نفسك كنت تجادل في أن الاثنين اصطفما بشكل وثيق بما فيه الكفاية بحيث لم تكن مشكلة.

نعم هذا هو جيثب. في قضية مغلقة بالفعل ، حيث كنت أضيف أفكاري فقط حول سبب شعوري بأن Rune كان جيدًا لأن هناك بعض السوابق الراسخة في الاسم. هذا ليس المكان أو السياق لكتابة أطروحة مليئة بالتعريفات الشاملة والكلمات المختارة بعناية. على سبيل المثال ، إذا كنت أضع العلاقات العامة لـ ، على سبيل المثال ، وحدة فك ترميز UTF-8 ، فلن أصف صراحة سبب تطبيق Hoehrmann DFA على الطرق البديلة. سأقول فقط "ها هو ، إليك بعض الأدلة على أنه يعمل ، وإليك بعض المعايير التي تدعم سبب استخدامي لهذا".

حجتي هي أن الناس سوف يخلطون بينه وبين مجموعات الحروف الرسومية وحروف الحروف

إنهم لا يخلطون بين أي مما سبق ذكره ، ولا Tree ، Heap ، Table ، Key ، Socket ، Port ...

هذه حجة مخادعة للغاية. ليس من السهل الخلط بين قطعة من الخيط وسلسلة من النص. ليس من السهل الخلط بين النبات طويل القامة وبنية بيانات الشجرة. من ناحية أخرى ، فإن نقطة الكود هي مفهوم غير مفهوم جيدًا من قبل معظم المبرمجين ، ويتم الخلط بينه وبين جميع المفاهيم الأخرى التي ناقشناها. الحل ، كما قلت ، هو قراءة الوثائق. ومع ذلك ، فإن اللغة التي تستخدم اسمها "الذكي" لنقاط الرمز تجعل الأمر أكثر صعوبة لتطبيق المعرفة من وثائق Unicode الفعلية إلى تلك اللغة. وهذا يقودني إلى هذا:

أصبحت هذه المصطلحات معايير واقعية ، بسبب اتفاقية راسخة في هذا المجال: لغتنا.

وهذا هو جوهر كل شيء. يبدو أنك تدعي أن مصطلح "rune" هو مصطلح راسخ لنقطة رمز مفهومة على نطاق واسع في البرمجة ، أو يجب أن تكون كذلك. إذا كان هذا هو السابق ، فأنا أدعوك لأن تسأل مبرمجًا متوسط ​​الخبرة في لغة برمجة رئيسية أخرى غير Go إذا كان قد سمع بها من قبل. إذا كان هذا هو الأخير ، فسأطلب منك نقطة التنافس مع مصطلحات Unicode الرسمية في موقف مربك بالفعل وغير مفهوم جيدًا والذي كثيرًا ما يساء فهمه حتى من قبل المطورين ذوي الخبرة العالية.

مدخلات Entomy outsider: حجةك بأكملها ، على حد علمي ، هي "محيرة وسيئة ، نعم ، لكنها ليست محيرة وسيئة".
وبالتالي؟ لماذا لا يمكن أن تكون جيدة بدلاً من ذلك؟ ما هي المشكلة في تسميته بالضبط ما يسميه يونيكود؟
أيضًا ، لا تعتبر الأحرف الرونية نقاطًا للتشفير ، أو حتى رموز حروف أو مجموعات ، في مجال الحوسبة العام. إذا كنت تبحث عن "Unicode runes" في Google ، فلن يظهر أي شيء يتعلق بها بنقاط الكود حتى الصفحة 2 ، وحتى ذلك الحين فهي مجرد روابط godoc / Nim. حتى في DuckDuckGo ، الذي قد يكون المبرمجون أكثر راحة في التعامل معه ، لا تزال نتيجة الصفحة 2. لذا فإن الحجة الوحيدة المتبقية للاسم الذي رأيته هي أنه من البديهي أنه يمثل نقطة رمز ، لكنه ليس كذلك . من البديهي أنه يمثل مجموعة حروف حروف ، أو ربما مجرد حرف حروف.
المصدر: لقد استخدمت Go واعتقدت أنه كان حرفًا حرفيًا حتى بعد أربع سنوات عندما قرأت هذا العدد للتو.

(والقول بأنه لا بأس في أنه يقترح حرفًا حرفيًا لأنه "قريب بما فيه الكفاية" يذكرني بحرف 16 بت قريبًا بدرجة كافية.)
نعم ، إذا كان المبرمجون أكثر ذكاءً وقراءة المزيد من الوثائق ، فلن نحتاج إلى اسم ذي معنى له ، أو حتى نوع على الإطلاق. سيعرف الناس فقط تمرير نقاط الرمز في int around بدلاً من char. لكنهم ليسوا كذلك. إنهم أذكياء كما هم الآن ، ولن يتغير ذلك لمجرد إضافة واجهة برمجة تطبيقات أخرى. الهدف هو زيادة كمية البرامج التي تتعامل بشكل صحيح مع لغات أخرى غير اللغة الإنجليزية ، وليس فقط تقديم طرق جديدة للقيام بنفس الشيء والحفاظ على نفس الحواجز التي تحول دون الدخول كما كان من قبل.

فقط من أجل الجدل ، ولأغراض علمية ، أود توجيه الجميع هنا إلى لغة برمجة واحدة تتعامل مع نص Unicode بشكل أفضل ، حيث يتم تعريف "الأفضل" بـ "الأقرب وفقًا لمعيار Unicode" ، وليس عن طريق تزوير البساطة: سريع

  • String هو مخزن مؤقت لنص Unicode التعسفي.
  • Character ، التي تقوم بتكرارها وما لا تفعله ، ليست قيمة Unicode العددية واحدة ، ولكنها مجموعة حروف حروف ممتدة. انظر هذا المثال عن مجموعة حروف الحرف اليدوية : let decomposed: Character = "\u{1112}\u{1161}\u{11AB}" // ᄒ, ᅡ, ᆫ
  • إذا كنت بحاجة إلى قيم Unicode العددية ، فيمكنك تكرارها أيضًا. نوعهم يسمى UnicodeScalar .
  • وإذا كنت تشعر حقًا أنك بحاجة إليه ، فيمكنك أيضًا التكرار على وحدات كود UTF-8 و UTF-16 ، مما ينتج عنه UInt 8 s و UInt 16 s.

الآن ، أنا لست هنا أقترح أن يكون C # بأسلوب Swift الكامل. في حين أن هذا سيكون مذهلاً ، إلا أنه يتطلب الكثير من التغييرات والعمل المطلوب. أنا هنا لأقترح اختيار تسمية بأسلوب Swift ، ومع ذلك ، لجميع الأسباب التي أشار إليها Serentty ، وترك الخيار مفتوحًا لتحويل السلاسل النصية بأسلوب Swift في النهاية.

بعض الأسماء المحتملة الأفضل من Rune : CodeUnit32 ، UnicodeScalar ، CodeUnit ، UniScalar ، UnicodeValue ، UniValue ، UnicodeScalarValue . أعتقد أن الأولين قد يتناسبان بدقة مع اصطلاحات تسمية C #. لاحظ أن UnicodeScalar هو الاسم الأفضل بشكل موضوعي ، لأن وحدات الكود هي مجرد طرق لترميز قيمة Unicode العددية في لغة Unicode. لذا فإن CodeUnit32 يعني التكرار على وحدات الكود لسلسلة نصية مشفرة UTF-32 ، بينما UnicodeScalar غير ترميز.

تحرير: نعم ، الاسم System.Rune موجود بالفعل. كل هذا مجرد "إذا أردنا أن نجعله أفضل قبل أن يبلغ عمر هذا الشيء نصف عقد".

@ نكهة فطيرة

حجتك بأكملها ، بقدر ما أستطيع أن أقول ، هي "محيرة وسيئة ، نعم ، لكنها ليست مربكة وسيئة".

لا هذه ليست حجتي على الإطلاق. أنا أبذل قصارى جهدي مع الإعاقة التي أعاني منها ، لكن هذا ليس تواصلي المقصود.

إذا كنت تبحث عن "Unicode runes" في Google ، فلن يظهر أي شيء يتعلق بها بنقاط الكود حتى الصفحة 2 ، وحتى ذلك الحين فهي مجرد روابط godoc / Nim.

إذا بحثت عن "سلسلة Unicode" في Google ، فلن تحصل على وجه التحديد على كيفية عمل سلاسل .NET أيضًا. هذه مسألة البحث عن شيء مجاور. كتشبيه صارم للغاية ، أنا أبرمج في كل من .NET و Ada ؛ string ليس هو نفسه بينهما ، وبعض القراءة الطفيفة لكل منهما فكرة جيدة.

التعريفات المثقلة بالأعباء ليست غير مألوفة في اللغة ، ومع ذلك فإننا ننجح في حل المشكلة. قد يفاجئك ذلك ، لكن كلمة "run" بها 179 تعريفًا رسميًا على الأقل ، و "take" بها 127 تعريفًا على الأقل ، و "break" بها على الأقل "123" ، وهكذا. [ المصدر ] يتمتع الأشخاص بقدرات مذهلة ويمكنهم بنجاح تجاوز تعقيدات أكثر بكثير مما يعتبر مشكلة هنا. إن القلق من وجود تعريفين رسميين على الأقل لـ "rune" ، في رأيي ، ليس له ما يبرره عندما يمكن إظهار أن الأشخاص يتعاملون مع أكثر من 50 ضعفًا من الأحمال الزائدة.

علاوة على ذلك ، فإن هذا يستغل بشكل صارخ سلوك محرك البحث. في معظم محركات البحث ، تحصل على نتائج بناءً على عدد الصفحات التي ترتبط بشيء ما. هناك عوامل أخرى أيضًا ، مع كل نهج يرجح الأشياء بشكل مختلف. نظرًا لأن .NET Rune هو مفهوم حديث إلى حد ما بالمقارنة ، سيكون هناك محتوى أقل بكثير يتحدث عنه ، وسيستغرق الأمر المزيد من الصفحات للوصول إليه. ولكنه يستخدم أيضًا أداة بحث خاطئة. إذا كنت أرغب في العثور على بحث حول خوارزميات البحث عن السلاسل ، لمعرفة ما إذا كان هناك أي شيء جديد قد ظهر في السنوات القليلة الماضية ، فأنا لا أبحث في Google أو DDG. يعتبر الباحث الدلالي والباحث العلمي من Google وغيرهما نقاط انطلاق أفضل. وبالمثل ، إذا كنت تريد فهم أشياء عن .NET API ، فابحث في MSDocs أولاً. إذا اشتكيت من أن مصطلح "لحظة القصور الذاتي" ، وهو مصطلح فيزيائي / هندسي ، غامض أو مضلل في اسمه ، ويجب إعادة تسميته لأنني لا أجد أي معلومات عنها في الكتب القليلة الأولى ، بدءًا من أقل رقم في مكتبة باستخدام تصنيف ديوي العشري ، لا توجد مشكلة في تسمية "لحظة القصور الذاتي" ؛ من الواضح أنني أبحث في المكان الخطأ.

المصدر: لقد استخدمت Go واعتقدت أنه كان حرفًا حرفيًا حتى بعد أربع سنوات عندما قرأت هذا العدد للتو.

لقد بحثت في مستندات Go وملاحظات الإصدار ، على الأقل تلك التي يمكن أن أجدها ، ويجب أن أتفق معك. إنها غامضة للغاية بشأن ماهية rune ، وللأسف فهي غامضة حتى حول حجم rune . أظن أن هذا الغموض سيسبب مشاكل لاحقًا ، حيث رأيت Ada بنفس القدر من الغموض بشأن قيود نوع البيانات وجعلها تعض نفسها في المؤخرة بعد سنوات.

ومع ذلك ، يجب أن أقول إن msdocs يقوم بعمل أفضل بكثير مع وصف مفصل وموجز للغاية.

يمثل قيمة عددية Unicode ([U + 0000..U + D7FF] ، ضمناً ؛ أو [U + E000..U + 10FFFF] ضمناً).

ومع ذلك ، فإن الملاحظات غير موجودة إلى حد ما وبعض التفاصيل حول سبب وجود Rune ومتى تريد استخدامه سيكون مفيدًا (وأيضًا المكان المناسب للحصول على شرح أكثر تفصيلاً من الشرح المبسط أعلاه) . سوف أطرح بعض التحسينات هناك.

تضمين التغريدة

من أجل الجدل فقط ، ولأغراض علمية ، أود توجيه الجميع هنا إلى لغة البرمجة التي تتعامل مع نص Unicode بشكل أفضل

هذا رأي. واحد أتفق معه تمامًا ؛ يتعامل Swift بالتأكيد مع UNICODE الحديثة بشكل أفضل. ولكن بدون الاستشهاد بأبحاث قابلة للتكرار تمت مراجعتها من قبل النظراء تؤكد هذه النتائج ، فإن هذا ليس ادعاءً علميًا.

الآن ، أنا لست هنا أقترح أن يكون C # بأسلوب Swift الكامل. في حين أن هذا سيكون مذهلاً ، إلا أنه يتطلب الكثير من التغييرات والعمل المطلوب.

وسوف يكسر البرامج الموجودة.

اترك الخيار مفتوحًا لتحويل نمط Swift للسلاسل النصية في النهاية.

وسوف يكسر البرامج الموجودة.

نعم ، اسم System.Rune موجود بالفعل. كل هذا مجرد "إذا أردنا أن نجعله أفضل قبل أن يبلغ عمر هذا الشيء نصف عقد".

وسوف يكسر البرامج الموجودة.

كإفتراض ، إذا كان سيتم إجراء تغييرات على الاسم الحالي ، كيف تقترح البرنامج الحالي الذي يستهدف .NET Core 3.0 / 3.1 ، حيث يكون Rune قيد الاستخدام بالفعل ، يظل متوافقًا ، مع وجوده أيضًا اسم مختلف في وقت التشغيل الهدف في وقت لاحق؟

وسوف يكسر البرامج الموجودة.

كما ذكرت ، أنا فقط أجادل من منظور المبدأ والمثالية. لقد تم ذكر حقيقة الأشياء بكثرة. على الرغم من وجود بعض الفروق الدقيقة في كل ذلك:

  • لا يؤدي اتباع أسلوب Swift مع السلاسل إلى كسر البرنامج بالضرورة. إنها مجرد مسألة إضافة المزيد من أساليب وأنواع التعداد أعلى واجهة String الموجودة بالفعل. لا أقصد أشياء جذرية مثل تغيير System.Char إلى نوع مجموعة حروف الكتابة أو شيء من هذا القبيل من خلال ذلك.
  • إذا تم تغيير الغرض من اسم نوع حالي مثل System.Char لنوع مختلف ، إذن نعم ، سيكون هذا تغييرًا هائلاً. وتغيير غير مسؤول في ذلك. انا معك هناك.
  • NET Core 4.0 الافتراضي ، الذي يتحدث في SemVer ، يمكنه فعل أي شيء يريده. بخلاف ذلك ، فإن التغييرات حتى 4.0 افتراضي ليست مخيفة: قم بتحويل System.Rune إلى اسم مستعار من النوع المهمل لـ System.UnicodeScalar أو أيًا كان الاسم. لن تلاحظ البرامج التي تستخدم Rune فرقًا ، باستثناء ملاحظة الإيقاف ، ويمكن للبرنامج الجديد استخدام النوع الفعلي الأفضل تسميته. و 4.0 افتراضي بعد ذلك يسقط Rune .
  • وبالمثل ، يمكن تحويل System.Char إلى اسم مستعار مقابل System.CodeUnit16 أو شيء من هذا القبيل.
  • إن القيام بذلك بأسلوب Swift يعني ببساطة إضافة System.GraphemeCluster في المزيج.
  • قد يكون إدخال المزيد من الأسماء المستعارة الجديدة للكلمات الرئيسية لجميع هذه الأنواع مشكلة.

فقط أسقط الطعام للتفكير هنا. أعتقد أن System.Rune ، في حين أن اسمًا سيئًا لغرضه ، لا يجعل حالة التسمية السابقة على حالها أسوأ. أعتقد أنه من الرائع أن يكون هناك أخيرًا نوع مناسب قادر على ترميز جميع أحجام Unicode. أرى فرصة جيدة لنشر اتجاه أكثر دقة في معالجة وتسمية Unicode. فرصة للجميع هنا أحرار في تنحيتها جانبًا.

مرحبًا بالجميع - الاسم System.Text.Rune هو ما تم شحنه وما نستخدمه من الآن فصاعدًا. كانت هناك مناقشة كبيرة (وساخنة!) في وقت سابق حول استخدام الاسم UnicodeScalar بدلاً من Rune ، ولكن في النهاية فاز Rune . لا يطرح الفريق فكرة اختيار اسم مختلف له في الوقت الحالي. وبينما أعلم أن الناس متحمسون لهذا الأمر وسنواصل مراقبة المحادثة هنا ، يجب أن ندرك في النهاية أن أي طاقة يتم إنفاقها لمواصلة التقاضي بشأن قضية التسمية لن تعود بالفوائد.

للتوضيح ووفقًا للمستندات: النوع System.Text.Rune في .NET يعادل تمامًا قيمة عددية Unicode. يتم فرض هذا عن طريق البناء. هذا يجعله أكثر تشابهًا مع نوع Swift's UnicodeScalar أكثر من نوع Go's rune .

هناك جهد جاري لإضافة قسم إلى مستندات Rune يوضح بالتفصيل حالات استخدامه وكيفية ارتباطه بواجهات برمجة تطبيقات معالجة النصوص الأخرى في .NET والمفاهيم في Unicode. توجد مشكلة التتبع على https://github.com/dotnet/docs/issues/15845. هناك أيضًا رابط من مشكلة التتبع هذه إلى مسودة حالية لمستندات المفاهيم.

بالنسبة لي ، فإن العيب الرئيسي في UnicodeScalar هو التباين الكبير بين طول اسم النوع وحجم البيانات من النوع. إنه في الأساس int مع بعض الفجوات في مجاله.

ومع ذلك ، فإن الإسهاب في الاستخدام سيكون شديدًا:

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

مقابل ما يعادل char أكثر من string (ويفضل أن يستخدم الأشخاص النوع الجديد فوق char لأنها قيم كاملة بدلاً من احتوائها على قيم مقسمة)

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

Rune هو حل وسط في إسهاب اسم النوع:

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

تضمين التغريدة

أهلا! لأكون صريحًا ، لقد وقعت في هذه الحجة ليس لأنني أحاول إقناع مستخدمي .NET بأن الاسم بحاجة إلى تغيير ، حيث يبدو أن تلك السفينة قد أبحرت ، ولكن ببساطة لأنني أردت التعبير عن رأيي لـ آخرون في هذا الموضوع اختلفوا معه. أعتقد أنه من الرائع أن يكون لدى C # نوع حرف _real_ في النهاية على عكس نوع الحرف المكسور الذي كان موجودًا لفترة طويلة ، والاسم ثانوي تمامًا لذلك. أفهم أن هناك توازنًا كبيرًا يجب تحقيقه بين الإيجاز والدقة ، وعلى الرغم من أنني كنت سأضع المكان المناسب في مكان ما حول CodePoint ، إلا أنني أفهم سبب اختلاف الآخرين.

ولكن مرة أخرى ، أود أن أشكرك على كل العمل الجاد في تحديث دعم Unicode الخاص بـ .NET! هذا شيء يحدث فرقًا كبيرًا لكثير من الناس حول العالم.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات