عمل نسخة من هيكل في Go

يمكن نسخ متغير البنية في Go إلى متغير آخر بسهولة بالغة باستخدام تعليمة الإسناد:

package main

import ( “fmt” )

type Dog struct { age int name string }

func main() { roger := Dog{5, “Roger”} mydog := roger if roger == mydog { fmt.Println(“Roger and mydog are equal structs”) } }

لعب

mydogوrogerمتغيرين منفصلين ، لكن عند مقارنتهما خاصية تلو خاصية فهما متماثلان تمامًا

يمكننا الآن تعديل كل خاصية لهذه المتغيرات دون التأثير على الكائن الآخر ، لأنDogبنية تحتوي على أنواع أساسية ، يتم نسخها حسب القيمة.

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

على سبيل المثال

type Cat struct {
    age int
    name string
    friends []string
}

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

أنسخة عميقةوهناك حاجة.

نسخة عميقة من هيكل

يمكنك إجراء هذه النسخة العميقة يدويًا. في حالة وجود شريحة ، يمكنك إجراء النسخة على النحو التالي:

package main

import ( “fmt” )

type Cat struct { age int name string friends []string }

func main() { wilson := Cat{7, “Wilson”, []string{“Tom”, “Tabata”, “Willie”}} nikita := wilson

<span style="color:#a6e22e">nikita</span>.<span style="color:#a6e22e">friends</span> = make([]<span style="color:#66d9ef">string</span>, len(<span style="color:#a6e22e">wilson</span>.<span style="color:#a6e22e">friends</span>))
copy(<span style="color:#a6e22e">nikita</span>.<span style="color:#a6e22e">friends</span>, <span style="color:#a6e22e">wilson</span>.<span style="color:#a6e22e">friends</span>)

<span style="color:#a6e22e">nikita</span>.<span style="color:#a6e22e">friends</span> = append(<span style="color:#a6e22e">nikita</span>.<span style="color:#a6e22e">friends</span>, <span style="color:#e6db74">"Syd"</span>)

<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">wilson</span>)
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">nikita</span>)

}

لعب

سوف ينتج عن الكود أعلاهويلسونمستخدم{7 Wilson [Tom Tabata Willie]}ونيكيتامستخدم{7 Wilson [Tom Tabata Willie Syd]}

لذا يمكنك أن ترى أن الشريحة هي كائن مختلف تمامًا ، وليست مجرد إشارة إلى نفس الشريحة.

استخدام مكتبة نسخ عميقة

https://github.com/jinzhu/copierهو (واحد من العديد) نسخ عميقة / مساعدين هناك. إنه يجعل من السهل حقًا نسخ البنية بشكل عميق دون إدارة كل حقل بشكل صريح. هذا مثال ، كل ما نحتاجه هوcopier.Copy(&nikita, &wilson)ونحن على استعداد:

package main

import ( “fmt” github.com/jinzhu/copier )

type Cat struct { age int name string friends []string }

func main() { wilson := Cat{7, “Wilson”, []string{“Tom”, “Tabata”, “Willie”}} nikita := Cat{} copier.Copy(&nikita, &wilson)

<span style="color:#a6e22e">nikita</span>.<span style="color:#a6e22e">friends</span> = append(<span style="color:#a6e22e">nikita</span>.<span style="color:#a6e22e">friends</span>, <span style="color:#e6db74">"Syd"</span>)

<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">wilson</span>)
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">nikita</span>)

}


المزيد من دروس Go: