Is it possible to convert from type to another type

I have a type

 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:"-"`
 }

Is it possible to convert this type into this one

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

In short, no, but give a read to the conversions section here. This is of particular interest:

A non-constant value  `x`  can be converted to type  `T`  in any of these cases:

* `x`  is [assignable](https://golang.org/ref/spec#Assignability) to  `T` .
* ignoring struct tags (see below),  `x` 's type and  `T`  have [identical](https://golang.org/ref/spec#Type_identity) [underlying types](https://golang.org/ref/spec#Types).
* ignoring struct tags (see below),  `x` 's type and  `T`  are pointer types that are not [defined types](https://golang.org/ref/spec#Type_definitions), and their pointer base types have identical underlying types.
* `x` 's type and  `T`  are both integer or floating point types.
* `x` 's type and  `T`  are both complex types.
* `x`  is an integer or a slice of bytes or runes and  `T`  is a string type.
* `x`  is a string and  `T`  is a slice of bytes or runes.

Of course, this is the obvious way of going from one to the other:

//let's say ft is a firstType var
st := secondType{
 ID: ft.Id,
 Name: ft.Name,
}

If you need to do these regularly, maybe a method or function would be of help:

func (ft firstType) Marshal() (secondType, err) {
  //Make some checks on ft fields if you need to.
  return secondType{
   ID: ft.Id,
   Name: ft.Name,
 }, nil
}
1 Like

Good examples. But why do you return an error from the Marshal function. Is it because some future error if the input isn’t convertible?

No special reason really, just in case he wanted to handle some checks. This is just an example:

func (ft firstType) Marshal() (secondType, err) {
  //For some reason, name can't be empty and id must be greater than 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
}

But of course, this is just fine (and alternatives using pointers, or a function instead of a method, etc., too):

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

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.