Golang中如何实现类型之间的转换

Golang中如何实现类型之间的转换 我有一个类型

type firstType struct {
    Id                   int64    `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
    Name                 string   `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

是否可以将此类型转换为以下类型

type secondType struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

更多关于Golang中如何实现类型之间的转换的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

很好的示例。但是为什么要在 Marshal 函数中返回错误呢?是因为如果输入无法转换可能会导致未来的错误吗?

更多关于Golang中如何实现类型之间的转换的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这并没有什么特别的原因,只是以防他需要处理一些检查。这只是一个示例:

func (ft firstType) Marshal() (secondType, err) {
  //出于某种原因,名称不能为空且ID必须大于0。
  if ft.Name == "" {
    return secondType{}, errors.New("name must be set")
  }
  if ft.Id <= 0 {
    return secondType{}, errors.New("id must be greater than 0")
  }
  return secondType{
   ID: ft.Id,
   Name: ft.Name,
 }, nil
}

但当然,这样写也是完全可以的(以及使用指针、或者使用函数而非方法等替代方案):

func (ft firstType) Marshal() (secondType) {
  return secondType{
   ID: ft.Id,
   Name: ft.Name,
 }
}

简而言之,不可以,但请阅读此处的类型转换章节。以下内容尤其值得关注:

非常量值 `x` 在以下任一情况下可转换为类型 `T`:

* `x` 可[赋值](https://golang.org/ref/spec#Assignability)给 `T`
* 忽略结构体标签(见下文),`x` 的类型和 `T` 具有[相同](https://golang.org/ref/spec#Type_identity)的[底层类型](https://golang.org/ref/spec#Types)
* 忽略结构体标签(见下文),`x` 的类型和 `T` 是指针类型且非[定义类型](https://golang.org/ref/spec#Type_definitions),其指针基类型具有相同的底层类型
* `x` 的类型和 `T` 均为整数或浮点类型
* `x` 的类型和 `T` 均为复数类型
* `x` 是整数或字节切片或符文切片,`T` 是字符串类型
* `x` 是字符串,`T` 是字节切片或符文切片

当然,这是最直接的转换方式:

// 假设 ft 是 firstType 变量
st := secondType{
 ID: ft.Id,
 Name: ft.Name,
}

如果需要经常进行此类转换,定义方法或函数会很有帮助:

func (ft firstType) Marshal() (secondType, err) {
  // 如有需要,可对 ft 字段进行校验
  return secondType{
   ID: ft.Id,
   Name: ft.Name,
 }, nil
}

在Go语言中,结构体类型之间的转换需要手动处理,因为它们是不同的类型。以下是实现从firstTypesecondType转换的代码示例:

package main

import "fmt"

type firstType struct {
    Id                   int64    `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
    Name                 string   `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

type secondType struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

// 转换函数
func convertFirstToSecond(ft firstType) secondType {
    return secondType{
        ID:   int(ft.Id), // int64 到 int 的显式转换
        Name: ft.Name,
    }
}

func main() {
    // 创建 firstType 实例
    ft := firstType{
        Id:   123456789,
        Name: "Example Name",
    }

    // 转换为 secondType
    st := convertFirstToSecond(ft)
    
    fmt.Printf("Original: %+v\n", ft)
    fmt.Printf("Converted: %+v\n", st)
}

输出结果:

Original: {Id:123456789 Name:Example Name XXX_NoUnkeyedLiteral:{} XXX_unrecognized:[] XXX_sizecache:0}
Converted: {ID:123456789 Name:Example Name}

如果需要处理多个字段或更复杂的转换逻辑,可以扩展转换函数:

func convertFirstToSecondAdvanced(ft firstType) secondType {
    st := secondType{}
    st.ID = int(ft.Id)
    st.Name = ft.Name
    return st
}

注意:由于firstType中的Id字段是int64类型,而secondType中的ID字段是int类型,需要进行显式类型转换。在64位系统上,int通常是64位,但为了确保类型安全,显式转换是必要的。

回到顶部