Command Palette

Search for a command to run...

כיצד למפות JSON כדי לעבור מבנים עם תגי שדה

כיצד למפות JSON כדי לעבור מבנים עם תגי שדה

T
Toolz Team
|Aug 31, 2026|16 קריאה דקות
העדיפו את Toolz.dev בגוגל

חלק מאוסף כלי נתונים

JSON ללכת מבנה

המר JSON לתוך Go struct הגדרות עם תגיות json אובייקטים מקוננים הופכים ל-inline structs, מערכים של אובייקטים מתמזגים, ושמות שדות עוקבים אחר מוסכמות Go. מפעיל את צד הלקוח.

השתמש ב-JSON ללכת מבנה

רוב העבודה היומיומית שלי היא TypeScript ו-PHP, אבל חלק ניכר מהכלים מאחור Toolz.dev והשירותים הקטנים שאני כותב סביבו הוא Go, ובכל פעם שאני חוט למעלה לקוח API חדש אני מכה באותו קיר יש לך תגובת JSON מולך, ואתה צריך את Go struct ש json.Unmarshal יפענח את זה לתוך כתיבת המבנה הזה ביד זה מייגע בצורה מאוד ספציפית: זה לא קשה, זה רק בטירוף, והחתיכות המטופשות הן בדיוק המקום שבו אתה עושה טעויות אז בניתי ממיר לאתר, וזה המדריך אליו.

TL;DR: הכליז ממיר מבנה JSON to Go מנתח מסמך JSON ופולט את ההצהרות מסוג Go שמתארות אותו אובייקטים הופכים למבנים מוטבעים, מערכים של אובייקטים מתמזגים למבנה אחד, וכל שדה מקבל א json:"key" תג אז encoding/json ממפה את הנתונים בחזרה בצורה נכונה שמות שדות עוקבים אחר מוסכמות Go, אז id הופך ID ו user_url הופך UserURL. החלף מספרים שלמים ל int64, הוסף omitempty, ושנה את שם סוג השורש. זה פועל לחלוטין בצד הלקוח: אין העלאה, אין הרשמה, עובד במצב לא מקוון.

מהו ממיר מבנה JSON to Go?

ממיר מבנה JSON to Go הופך מסמך JSON להצהרות מסוג Go המתארות אותו, כך שתוכל לפענח את אותם נתונים עם הספרייה הסטנדרטית's encoding/json חבילה במקום להקליד את ה-struct ביד כל אובייקט JSON הופך ל-Go struct, כל שדה נושא א json:"key" תג שממפה אותו בחזרה לשם המקורי, והסוגים הסקלרים מוסקים מהערכים. מחרוזת JSON הופכת string, מספר שלם הופך int, מספר עם נקודה עשרונית הופך float64, true ו false להפוך ל bool, ו null הופך interface{}.

הסיבה שזה שימושי היא שאובייקט JSON ומבנה Go מתארים את אותה צורה, קבוצה של שדות בעלי שם עם ערכים מוקלדים, אבל Go מוקלד סטטית ו-JSON לא, אז המבנה צריך לאיית כל סוג מלפנים. גזירת הסוגים הללו מתגובת מדגם היא מכניקה טהורה, ומכניקה הנעשית ביד על פני מטען מקונן היא המקום שבו חיים הבאגים. הממיר עושה את הגזירה באופן דטרמיניסטי ומחזיר לך בלוק סוג שמתחבר.

כדאי להיות ברור לגבי שני חצאי הבעיה, כי הם מה שממיר נאיבי טועה. הראשון הוא מתן שמות: Go מקודד רק שדות מיוצאים, אלה עם אות ראשונה גדולה, וכללי המוך הקהילתיים רוצים ראשי תיבות משותפים באותיות רישיות מלאות. השני הוא התג: ה json:"..." התג צריך להחזיק את המפתח המקורי המדויק או json.Unmarshal מדלג בשקט על השדה בזמן ריצה ללא שגיאה טעו והפענוח שלכם מחזיר מבנה מלא באפס ערכים בזמן שהכל נראה בסדר הכלי מטפל בשניהם בשבילכם.

למה לא לכתוב את המבנה ביד?

זו השאלה הכנה, כי עבור אובייקט שטוח בן שלושה שדות, כתיבת יד המבנה מהירה יותר מפתיחת כלי הממיר מרוויח את מקומו בתגובות שאינן שטוחות: מטען עם אובייקטים מקוננים, מערכי אובייקטים, ועשרים שדות שבהם נמצאים חצי מהמפתחות snake_case וכמה הם ראשוני כמו id, url, ו api_key.

בתגובה כזאת, לגרסה בכתב יד יש שלושה מצבי כשל שאני מכה שוב ושוב אתה שוכח לייצא שדה, אז הוא נשאר באותיות קטנות ו encoding/json מסרב לאכלס את זה אתה מנצל את השדה אבל שוכח את התג, אז UserName מחפש מפתח JSON שנקרא UserName ולעולם לא מוצא user_name. או שאתה טועה בקינון, מכריז על שדה כמבנה רגיל כאשר ה-JSON למעשה עוטף אותו במערך. אף אחת מאלה אינה שגיאות קומפילציה. אלו הפתעות בזמן ריצה שמופיעות כנתונים חסרים, ואתה מאבד יותר זמן באגים באחד מהם ממה שהיית משקיע ביצירת המבנה כולו.

הממיר מסיר את שלושתם הוא מייצא כל שדה, הוא כותב את התג מהמפתח האמיתי, והוא קורא את צורת ה-JSON בפועל כדי להחליט בין מבנה לפרוסת מבנים. מה שאתה מדביק זה בשביל מה אתה מקבל סוגים.

הנה ההחלטה בטבלה אחת.

מצב להשתמש למה
עצם שטוח עם שניים או שלושה שדות כתוב ביד מהר יותר מלפתוח כל דבר
תגובת API מקוננת עם שדות רבים ממיר מבנה JSON to Go שמות ותגים הם המקום שבו מבנים בכתב יד נשברים
אתה צריך את אותה צורה כמו TypeScript ממיר JSON ל-TypeScript אותה הסקה, שפת יעד שונה
אתה רוצה סכימת אימות, לא סוגים מחולל סכימה JSON טיוטת כללים 07 ולא סוגי Go

מדוע שמות שדות Go שונים ממפתחות ה-JSON שלי?

זה מכשיל אנשים בפעם הראשונה, אז כדאי להסביר ולא להסתיר. Go's encoding/json חבילה רק מרשלים ו unmarshals מיוצא struct fields, שפירושו שדות ששמם מתחיל באות גדולה.A JSON key like user_name לא ניתן למפות למי שאינו מיוצא user_name שדה, אז יש לשנות את שם השדה למשהו מיוצא. הכלי עושה שימוש באותיות רישיות בכל מילה, הופך user_name לתוך UserName.

נוסף על כך, קהילת Go's כלי מוך, הכללים שהתחילו עם golint ולחיות על בכלים כמו staticcheck, רוצה ראשי תיבות נפוצים כתובים בכל הכיתות. כך id הופך ID, לא Id; user_url הופך UserURL, לא UserUrl; ו html_body הופך HTMLBody. הממיר מכיר את הסט הסטנדרטי של ראשוניזמים, ID, URL, API, HTTP, JSON, UUID, והשאר, ומחיל אותם, כך שהפלט עובר את הלינטרים שה-CI שלך כנראה פועל.

החתיכה שהופכת את שינוי השם לבטוח היא התג. כל שדה מקבל א json:"user_name" תג מחזיק את המפתח המקורי בדיוק, אז בזמן ריצה json.Unmarshal קורא את מפתח JSON user_name וכותב את זה לתוך UserName שדה ללא קשר לשם מחדש. המאמר של Go blog's על JSON ו-Go מתעד את מנגנון התג הזה, וזו הסיבה ששדה ששמו שונה עדיין מפענח כהלכה. ללא התג, המבנה ששמו שונה לא יצליח בשקט לאכלס.

כיצד מטפלים במספרים ומערכים של אובייקטים?

שני חלקים של ההסקה ראויים לבדיקה מקרוב מכיוון שהם המקום שבו הממירים שונים באיכותם.

מספרים תחילה. ל-JSON יש סוג מספר בודד, אבל Go לא, אז הכלי צריך לבחור. ערך ללא חלק חלקי הופך int, או int64 אם אתה מפעיל את האפשרות הזו, וערך עם נקודה עשרונית הופך float64. המקרה המעניין הוא מערך שמערבב אותם, כמו [9.5, 8, 7.2]. אם הכלי הקליד את זה בתור []int זה לא יצליח לפענח את 9.5, אז זה מרחיב את כל הפרוסה ל []float64. כל מערך שבו אלמנט אחד מאלץ סוג רחב יותר מקבל את הסוג הרחב יותר עבור כל האלמנטים, שזו הבחירה היחידה שמפענחת כל ערך.

מערכים של אובייקטים הם המקום השני מטענים אמיתיים מקבלים מעניין API כמעט אף פעם לא נותן לך מערך שבו לכל אובייקט יש קבוצה זהה של מפתחות; לאלמנט אחד יש שדה שהאחרים משמיטים, או שדה nullable קיים כאן ונעדר שם אם הכלי יצר struct רק מהאלמנט הראשון, הוא היה מפיל את המפתחות שמופיעים מאוחר יותר במקום זאת הוא ממזג כל אובייקט במערך למבנה אחד שכולל כל מפתח שיש לכל אלמנט, ואם שני אלמנטים נותנים את אותם סוגי מפתח לא תואמים, נגיד מספר באחד ומחרוזת באחר, השדה הזה נופל בחזרה ל interface{} במקום שהכלי ינחש לא נכון או נכשל על הסף התוצאה היא סוג struct יחיד שיכול לפענח את המערך כולו.

איך אני משתמש בממיר?

הזרימה היא ארבעה שלבים הדבק אובייקט או מערך JSON בתיבת הקלט; אם אתה רוצה לראות תחילה את צורת הפלט, טען את המדגם. תן לסוג השורש שם, משהו כמו User או ApiResponse, והכלי מנקה אותו למזהה Go מיוצא חוקי כך שהוא מהדר כפי שנכתב. בחר int או int64 למספרים שלמים, ותדליק omitempty אם אתה רוצה שדות בעלי ערך אפס יישארו בחוץ כאשר המבנה מקודד מאוחר יותר בחזרה ל-JSON. לאחר מכן לחץ על המר והעתק את המבנה שלך .go קובץ.

אם ה-JSON אינו חוקי, הכלי מדווח על המנתח ' הודעת שגיאה משלו במקום להיכשל בשקט, כך שפסיק נגרר תועה או מפתח לא מצוטט ממהר למצוא ומכיוון שהכל פועל בדפדפן שלך, אתה יכול להדביק תגובת API אמיתית, כולל אחת עם שדות פרטיים, מבלי שהוא יעזוב את המחשב שלך. המודל הזה בצד הלקוח הוא אותו מודל מאחורי שאר האתר, המתואר ב- כלים מקוונים לפרטיות נתונים מדריך.

איך זה מתאים לכלי JSON האחרים?

ממיר המבנה של JSON to Go הוא חבר אחד במשפחה של שנאי JSON באתר, והם חולקים את אותה ליבת ניתוח. כאשר אתה רוצה לסדר את ה-JSON תחילה, ה פורמט JSON יכניס ויאמת אותו, מה שכדאי לעשות לפני שאתה ממיר כדי שתוכל לקרוא את הצורה שאתה עומד להקליד. כאשר שפת היעד שלך היא TypeScript ולא Go, ה ממיר JSON ל-TypeScript מריץ את אותה הסקה ופולט ממשקים. כאשר אתה צריך חוזה אימות במקום סוגי שפות, ה מחולל סכימה JSON מייצר סכימת Draft-07, וכאשר היעד הוא בסיס קוד PHP, ה ממיר מערך JSON ל-PHP כותב מערך מילולי.

החוט המחבר את כולם הוא שהם מתייחסים ל-JSON כמקור למבנה ומתרגמים את המבנה הזה לכל מה שבסיס הקוד שלך מדבר. אם אתה עובד על פני מספר שפות, ה ערכת כלים למפתחי אינטרנט roundup מראה כיצד החלקים הללו משתלבים יחד, וה מדריך כלי קידוד מכסה את הסט הרחב יותר של מעצבים וממירים.

דוגמה עובדת מבניית שירות Go

תן לי להפוך את זה לקונקרטי לפני זמן מה כתבתי שירות Go קטן שמשך נתונים מ-API של צד שלישי וחשף מחדש גרסה מצומצמת שלו. תגובת הספק 's הייתה אובייקט מקונן: רשומה ברמה העליונה עם א owner תת-אובייקט, א tags מערך מחרוזות, וא scores מערך שבאופן מעצבן ערבב מספרים שלמים ועשרונים בהתאם לשדה. הקלדת המבנה ביד פירושה לקבל את owner מקנן נכון, מתייג כל snake_case מפתח, והחלטה מה לעשות לגבי המערך המעורב הזה.

הדבקתי את תגובת המדגם לתוך הממיר, קראתי לסוג השורש על שם המשאב, וקיבלתי בחזרה מבנה עם Owner כמבנה מקונן מוטבע, Tags כ []string, ו Scores הורחב כהלכה ל []float64. ה id שדה יצא כמו ID עם א json:"id" תג, אז זה גם עבר את הלינטר וגם פענח את המפתח האמיתי העתקתי אותו ישר לחבילת הלקוח ועברתי להיגיון, ששם בעצם רציתי לבלות את הזמן שלי המבנה לא היה החלק המעניין בעבודה, ויצירתו פירושה שהוא הפסיק להיות כל חלק מהעבודה.

הסיבה שאני מושיט יד לממיר ולא למבנה בכתב יד בנקודות האלה היא לא עצלות, היא שהחלקים המכניים, הייצוא, התיוג והקינון, הם בדיוק החלקים שאני טועה כשאני חושב על ההיגיון במקום זאת. הורדתם לכלי דטרמיניסטי פירושה שהמבנה נכון בהידור הראשון, ופענוח נכון בריצה הראשונה, שבמטען מקונן חוסך הפעלת ניפוי באגים אמיתית. כשאני צריך שהמבנה ישרוד גם בקידוד מחדש, אני נדלק omitempty אז ערכי האפס נשארים מחוץ לפלט, והתגים מגיעים כמו json:"key,omitempty" מוכן לנסיעה הלוך ושוב ההיא.

מהם הגבולות שכדאי לדעת עליהם?

כמה קצוות כנים. הראשון הוא null. ג'ייסון null אינו נושא מידע סוג בפני עצמו, אז שדה שהוא null בדוגמה שלך מוקלד כ interface{}. אין שום דבר שהכלי יכול להסיק שם; אם אתה יודע את הסוג האמיתי, שנה אותו בעורך שלך לאחר ההדבקה, או הזין לממיר דוגמה שבה לשדה הזה יש ערך אמיתי כך שניתן לגזור את הסוג. זהו מאפיין של הנתונים, לא חסרון של הכלי.

השני הוא דיוק מספרי, והוא תכונה של ניתוח JSON באופן כללי ולא ממיר זה באופן ספציפי הכלי מנתח את ה-JSON שלך עם הדפדפן ' מנתח JSON, המייצג מספרים כצפים בעלי דיוק כפול, כך שמספרים שלמים מעבר ל-2 בערך בחזקת 53 מאבדים את הדיוק בזמן הניתוח, לפני שהכלי אי פעם רואה אותם int64 השדה רחב מספיק כדי להחזיק מזהה גדול, אבל אם המזהה מגיע כמספר JSON חשוף כל כך גדול, הניתוח כבר עיגל אותו. עבור מזהים שלמים גדולים באמת, המהלך החזק הוא לשאת אותם כמחרוזות ב-JSON, מה ששומר אותם מדויקים ומאפשר לך להקליד את השדה בתור string.

השלישית היא שהסקת מסקנות היא נקודת התחלה, לא בשורה הכלי נותן לך את הסוגים שבהם המדגם תומך, אבל רק אתה יודע ששדה שהוא במקרה מספר שלם בתגובה זו הוא באמת ספירה ניתנת לביטול, או ש-a float64 צריך להיות א json.Number כדי למנוע אובדן דיוק התייחסו לפלט כאל טיוטה ראשונה נכונה שאתם משכללים, לא חוזה מגולף באבן זה נכון לגבי כל מחולל JSON-to-types, בכל שפה.

לבסוף, הממיר מייצר מבנים מקוננים מוטבעים, ששומרים על כל הצורה בהצהרה אחת שאתה יכול להדביק כבלוק. זה הסגנון הנפוץ והקריא ביותר עבור מבנה שנוצר, וזה אילו כלים במערכת האקולוגית של Go הפכו פופולריים. אם אתה מעדיף להפריד סוגים בעלי שם עבור תת-אובייקטים בשימוש חוזר עמוק, כלומר רפקטור שאתה עושה ביד ברגע שהגרסה המוטבעת נמצאת בעורך שלך, וזו בדרך כלל תמצית של חמש שניות עם ה-IDE שלך.

שאלות נפוצות

מהו ממיר מבנה JSON to Go? ממיר מבנה JSON to Go הופך מסמך JSON להצהרות מסוג Go שמתארות אותו. כל אובייקט הופך למבנה, כל שדה מקבל json:"key" תג, וסוגי הערכים מוסקים, כך שתוכל לבטל את המארש של אותם נתונים עם קידוד/json מבלי לכתוב את המבנה ביד.

כיצד אוכל להמיר JSON למבנה Go? הדבק את ה-JSON שלך בתיבת הקלט, הזן שם לסוג השורש, בחר את האפשרויות השלם והתג שלך ולאחר מכן לחץ על המר. הכלי מדפיס הגדרות Go struct עם תגי json שתוכל להעתיק ישירות לקובץ.go.

מדוע שמות שדות Go שונים ממפתחות ה-JSON שלי? Go מקודד רק שדות מיוצאים, כך שכל שם שדה באותיות רישיות, וראשי תיבות נפוצים נעשים באותיות גדולות כדי להתאים לגולינט. ה-json:"..." התג בכל שדה שומר על המפתח המקורי, כך ש-json.Unmarshal עדיין ממפה את הנתונים בצורה נכונה למרות השדה ששמו שונה.

כיצד ממופים מספרי JSON לסוגי Go? מספר שלם הופך ל-int, או int64 אם אתה מפעיל את האפשרות הזו, ומספר עם נקודה עשרונית הופך ל-float64. כאשר מערך מערבב מספרים שלמים ועשרונים עבור אותו מיקום, הסוג מורחב ל-float64 כך שכל ערך מתאים.

כיצד מטפלים במערכים של אובייקטים? מערך של אובייקטים מתמזג למבנה יחיד הכולל כל מפתח שיש לכל אלמנט. אם שני אלמנטים נותנים את אותם סוגי מפתח לא תואמים, השדה הזה הופך לממשק{} כך שהמבנה עדיין מכסה את כל המערך.

מה קורה לערכי null? Null JSON אינו נותן מידע סוג בפני עצמו, כך שהשדה מוקלד כממשק{}. אם אתה יודע את הסוג האמיתי, שנה אותו בעורך שלך לאחר ההדבקה, או ספק ערך דוגמה לא ריק ב-JSON כך שניתן יהיה להסיק את הסוג.

האם ה-JSON שלי מועלה במקום כלשהו? מס 'ההמרה מתרחשת לחלוטין בדפדפן שלך באמצעות JavaScript במכשיר שלך.JSON שלך לעולם לא הועלה, נרשם או מאוחסן, והכלי ממשיך לעבוד עם הרשת מנותקת לאחר שהדף נטען.

האם ממיר המבנה של JSON to Go בחינם? כן. זה לגמרי בחינם ללא הרשמה, ללא סימן מים וללא מכסה שימוש. המר כמה מסמכי JSON ל-Go structs שאתה צריך עבור פרויקטים אישיים או מסחריים.

Comments

0 comments

0/2000 characters

No comments yet. Be the first to share your thoughts!