go - 如何将数据从一种类型复制到具有相同结构的另一种类型?
问题描述
在下面的代码中:
type ProductEntity struct {
ID int `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Price float32 `json:"price"`
SKU string `json:"sku"`
CreatedOn string `json:"-"`
UpdatedOn string `json:"-"`
DeletedOn string `json:"-"`
}
type ProductEntityList []*ProductEntity
type PostRequestModel struct {
ID int `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Price float32 `json:"price"`
SKU string `json:"sku"`
CreatedOn string `json:"-"`
UpdatedOn string `json:"-"`
DeletedOn string `json:"-"`
}
type RequestBody []*PostRequestModel
func convertModelToEntity(modelList RequestBody) ProductEntityList {
// return entity.ProductEntityList(modelList) // type conversion error
}
如何将具有相同结构的数据从一种类型复制到另一种类型?因为RequestBody
andProductEntityList
是两种不同的类型定义
解决方案
如果这些类型确实相等,请使用type alias:
type PostRequestModel = ProductEntity
如果你这样做,你可以简单地从转换ProductEntityList
为(在Go PlaygroundRequestBody
上试试):
func convertModelToEntity(modelList RequestBody) ProductEntityList {
return ProductEntityList(modelList) // Works!!
}
如果你不能使用类型别名,那么你就不能从一个切片转换到另一个切片。您必须创建一个新切片。请注意,您可以转换各个切片元素,因为指向的结构类型具有相同的字段。这是可能的,因为规格:转换:
在以下任何一种情况下,非常量值
x
都可以转换为类型:T
- [...]
- 忽略 struct 标记(见下文),
x
的类型 和T
是未定义类型的指针类型,它们的指针基类型具有相同的基础类型。
So*ProductEntity
可以转换为*PostRequestModel
(反之亦然),因为ProductEntity
and的基础类型PostRequestModel
是“相同”的结构类型。
在Go Playground上尝试一下:
func convertModelToEntity(modelList RequestBody) ProductEntityList {
r := make(ProductEntityList, len(modelList))
for i, m := range modelList {
r[i] = (*ProductEntity)(m)
}
return r
}
另请注意,如果RequestBody
和ProductEntityList
具有相同的内存布局(它们在您的示例中),您可以使用 packageunsafe
来简单地转换它们,但我宁愿避免它(在Go Playground上尝试):
func convertModelToEntity(modelList RequestBody) ProductEntityList {
return *(*ProductEntityList)(unsafe.Pointer(&modelList))
}
为什么要避免这种情况?使用包unsafe
您的应用程序可能会变得不可移植,并且 Go 1 兼容性保证可能不适用于它。例如,您可以向 only 添加一个字段,ProductEntity
但不能向PostRequestModel
. 结果,您的应用程序将继续编译而不会出现错误,但可能随时崩溃。始终将包裹unsafe
视为最后的手段。
推荐阅读
- javascript - 如何在左右滚动事件上知道容器 div 中心的子 div?
- angular - Karma/Jasmine angular spyOn 总是返回存根类的值
- unity3d - 如何在 Unity 中尽可能优化地检测与表面的碰撞?
- visual-studio-code - 使用 esbuild 包含或排除 node_modules
- git - 如何在 Git 中不进行任何更改的情况下取消暂存文件?
- bash - 如何在 if 语句中使用 wc -l 整数输出
- php - WordPress帖子上传时间问题
- javascript - 两个文本区域并排,最大尺寸填充整个覆盖网站,就像在崇高的文本编辑器中一样,有两列布局?
- java - 如果错误生成一次,Java while 循环会继续执行 catch 块中的代码
- android - 编辑填写的表格并使用 Ionic/Angular 重新提交