使用賦值語句,可以很容易地將Go中的struct變量複製到另一個變量:
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
struct包含基本類型,它們按值複製。
如果我們在結構體中有一個引用類型,這並不是那麼容易,因為pointer
將被複製,而不是值,因此它應該是淺拷貝。
例如
type Cat struct {
age int
name string
friends []string
}
我們的貓的朋友列表是一個切片,一個引用類型(以及指針,地圖,函數和通道),因此,如果您有一個貓對象,並且像上面的Dog示例一樣進行複制,則無法修改friends屬性,而不影響其他對象。
一種深拷貝是必需的。
深度複製結構
您可以手動執行這種深層複製。對於切片,可以執行以下複製:
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>)
}
更多教程:
- 使用NGINX反向代理服務Go服務
- 在Go中復制結構
- Go Web服務器的基礎
- 在Go中對地圖類型進行排序
- 簡而言之去指針
- 轉到標籤說明
- 開始日期和時間格式
- 使用Go進行JSON處理
- 可變參數函數
- 去弦備忘單
- 轉到空界面說明
- 使用VS Code和Delve調試Go
- 命名為Go返回參數
- 在Go中生成隨機數和字符串
- Go項目的文件系統結構
- Go中的二進制搜索算法
- 在Go中使用命令行標誌
- GOPATH解釋
- 使用Go構建一個命令行應用程序:lolcat
- 使用Go構建CLI命令:Cowsay
- 在Go中使用殼管
- Go CLI教程:財富克隆
- 使用Go列出文件夾中的文件
- 使用Go從GitHub獲取存儲庫列表
- 去,將一小段字符串附加到文件中
- 去,將字符串轉換為字節片
- 使用Go可視化您本地的Git貢獻
- Go CPU和內存分析入門
- 解決Go程序中的“不支持索引”錯誤
- 測量Go程序中的執行時間
- 使用Go構建Web爬網程序以檢測重複的標題
- 最佳實踐:指針還是價值接收者?
- 最佳實踐:您應該使用方法還是函數?
- Go數據結構:集
- 前往地圖備忘單
- 在Go中生成泛型類型的實現
- Go數據結構:字典
- Go數據結構:哈希表
- 在“通過通道”中實現事件偵聽器
- Go數據結構:堆棧
- Go數據結構:隊列
- Go數據結構:二進制搜索樹
- Go數據結構:圖形
- Go數據結構:鍊錶
- Go數據結構的完整指南
- 比較Go值
- Go是面向對象的嗎?
- 在Go中使用SQL數據庫
- 在Go中使用環境變量
- 上篇教程:PostgreSQL支持的REST API
- 在Go Web服務器上啟用CORS
- 在Docker容器中部署Go應用程序
- 為什麼Go是作為PHP開發人員學習的功能強大的語言
- 去,刪除io.Reader.ReadString換行符
- 開始,如何觀看更改並重建程序
- 去算一下自約會以來的月份
- 在Go中訪問HTTP POST參數