طريقة الاستخدام
- ألصق كائن JSON في كائن JSON. يجب أن يكون النص كله كائناً واحداً، بأقواس معقوصة في الأعلى.
- اكتب اسم الهيكل الجذري، مثل Product، وضع علامة على أضف omitempty إلى كل وسم إن أردت هذا الخيار.
- اقرأ الفحص. الأخضر يعني أن الكائن تحوّل، والأحمر يذكر المكان الذي فيه المشكلة.
- انسخ كود Go إلى ملف فيه جملة package، أو نزّله باسم models.go.
كيف تُختار أنواع Go
تأخذ كل قيمة في JSON النوع الذي يحفظها في Go. فالنص يصبح string، وtrue أو false يصبح bool. وتحدد قواعد Unmarshal في encoding/json (باللغة الإنجليزية) كيف يُقرأ JSON إلى هذه الأنواع.
- العدد الصحيح الذي يتسع في 64 بت يصبح int64. والعدد الذي فيه فاصلة عشرية أو أُس، مثل 1.0 أو 2e3، يصبح float64، وكذلك العدد الصحيح الأكبر من أن يتسع في int64.
- null يصبح any. وإذا جاء null بجانب قيمة من نوع آخر أخذ ذلك النوع، لأن null يترك قيمة Go من نوع آخر دون تغيير.
- الكائن يصبح هيكلاً، والقائمة تأخذ النوع الذي تشترك فيه عناصرها. تندمج الكائنات في القائمة الواحدة في هيكل واحد، وتصبح القائمة المختلطة الأنواع []any.
- الكائن الفارغ يصبح هيكلاً فارغاً، والقائمة الفارغة تصبح []any.
الأسماء والوسوم والتعارض
يأخذ كل حقل اسمه من اسم JSON: تُوصل الكلمات، ويبدأ كل منها بحرف كبير، فتصبح user-name هي UserName. ومواصفة Go (باللغة الإنجليزية) تُصدّر الحقل الذي يبدأ اسمه بحرف كبير، ولهذا يُكتب الحرف الأول كبيراً. ويحفظ وسم json الاسم كما كُتب، فيُطابَق المفتاح نفسه حين يُقرأ JSON.
إذا أعطى اسمان الاسم نفسه في Go أُضيف رقم إلى أحدهما، كما في AB وAB2، وينال الهيكل الذي اسمه مستعمل رقماً كذلك. ويُسمّى عنصر القائمة من اسم القائمة، فتعطي products هيكلاً اسمه Product، وإذا لم تكن للاسم قاعدة جمع أُضيفت اللاحقة Item.
- الاسم الذي فيه فاصلة، أو شرطة واحدة، أو لا يحتوي أي محرف، لا يصلح وسم json، فيسمّي المحوّل ذلك المفتاح ويتوقف.
- مع تفعيل omitempty يحصل كل وسم على هذا الخيار. ويكبّر المحوّل الحرف الأول من اسم الهيكل الجذري، فتصبح product هي Product.
ما لا يفعله المحوّل
- لا يضيف جملة package ولا استيرادات (imports). ألصق الكود في ملف له جملة package الخاصة به.
- لا يستعمل المؤشرات للحقول الاختيارية. فالحقل الذي يغيب في JSON أو يكون null لا يُميَّز عن الحقل الذي يحمل القيمة الصفرية.
- لا يغيّر الأسماء إلى الاختصارات الشائعة في Go، فتصبح id هي Id. غيّر اسم الحقل بيدك إن كان أسلوب كودك يريد ID.
مثال محلول: طلب فيه مالك وعنصران
يحتوي JSON في المثال على عدد صحيح، وعدد عشري، وكائن، وقائمة فيها كائنان. يعرض الجدول الحقل الذي يصبح عليه كل اسم في JSON. ويكتب المحوّل الهياكل الثلاثة تحت الجدول، والهيكل الخارجي Order أولاً.
| اسم JSON | حقل Go | نوع Go | الوسم |
|---|---|---|---|
| id | Id | int64 | json:"id" |
| ratio | Ratio | float64 | json:"ratio" |
| owner | Owner | Owner | json:"owner" |
| items | Items | []Item | json:"items" |
الأسئلة الشائعة
لماذا يكون العدد الصحيح int64 وليس int؟
النوع int64 عدد صحيح بإشارة وعرض ثابت 64 بت، ويتسع لكل عدد صحيح من -9223372036854775808 إلى 9223372036854775807. يستعمله المحوّل لكل عدد يتسع فيه، فلا تفيض القيمة. غيّر النوع إلى int بيدك إن كان كودك يحتاج ذلك.
لماذا يصبح null النوع any؟
ليس في Go نوع يحفظ null وحده، لذلك يستعمل المحوّل any الذي يحفظ أي قيمة. وإذا جاء null بجانب قيمة من نوع آخر أخذ ذلك النوع بدلاً منه، لأن encoding/json يترك قيمة Go من نوع آخر دون تغيير حين يقرأ null.
لماذا يُسمّى الحقل Id وليس ID؟
يكبّر المحوّل الحرف الأول من كل كلمة، ولا يطبّق اختصارات Go الشائعة، فتصبح id هي Id. ولا يتغير وسم json الذي يبقى id، فتُقرأ البيانات بالطريقة نفسها. أعد تسمية الحقل إن كان أسلوب كودك يطلب ID.
أي إصدار من Go يحتاجه الكود الناتج؟
يستعمل الكود any للقيمة null، وany اسم مستعار للنوع interface{} أُضيف في Go 1.18. فإذا كان كودك أقدم، استبدل any بالنوع interface{}، وهما النوع نفسه.
لماذا يرفض المحوّل بعض الأسماء؟
يحمل وسم json الاسم، وتبدأ خياراته بعد فاصلة، فلا يمكن كتابة اسم فيه فاصلة داخل الوسم. والوسم الذي فيه شرطة واحدة يخفي الحقل، لذلك يُرفض هذا الاسم أيضاً.
هل يُرسل JSON الذي ألصقه إلى أي مكان؟
لا. يجري التحويل داخل متصفحك، ولا يُخزَّن ما تلصقه ولا يُرسل إلى خادمنا. ولا تلصق كلمة مرور أو رمزاً سرياً في أي صفحة لا تثق بها.
المصادر
- Go: encoding/json، قواعد Unmarshal ووسوم البنية (باللغة الإنجليزية)
- مواصفة لغة Go: الأنواع العددية وany (باللغة الإنجليزية)
آخر مراجعة للأرقام والنص: الخميس، 2 جمادى الآخرة 1448 بعد الهجرة.