Golang:不同结构类型之间是否可以转换?

Let's say I have two similar types set this way :

type type1 []struct {
    Field1 string
    Field2 int
}
type type2 []struct {
    Field1 string
    Field2 int
}

Is there a direct way to write values from a type1 to a type2, knowing that they have the same fields ? (other than writing a loop that will copy all the fields from the source to the target)

Thanks.

For your specific example, you can easily convert it playground:

t1 := type1{{"A", 1}, {"B", 2}}
t2 := type2(t1)
fmt.Println(t2)

To give a reference to OneOfOne's answer, see the Conversions section of the spec.

It states that

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

  • x is assignable to T.
  • x's type and T have identical underlying types.
  • x's type and T are unnamed pointer types 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.

The first and highlighted case is your case. Both types have the underlying type

[]struct { Field1 string Field2 int }

An underlying type is defined as

If T is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type is T itself. Otherwise, T's underlying type is the underlying type of the type to which T refers in its type declaration. (spec, Types)

You are using a type literal to define your type so this type literal is your underlying type.

Nicolas, in your later comment you said you were using field tags on the struct; these count as part of definition, so t1 and t2 as defined below are different and you cannot cast t2(t1):

type t1 struct {
    Field1 string
}

type t2 struct {
    Field1 string `json:"field_1"`
}

UPDATE: This is no longer true as of Go 1.8

As of Go 1.8, struct tags are ignored when converting a value from one struct type to another. Types type1 and type2 will be convertible, regardless of their struct tags, in that Go release. https://beta.golang.org/doc/go1.8#language

You can manually use a mapper function which maps each element of type t1 to type t2. It will work.

func GetT2FromT1(ob1 *t1) *t2 {
     ob2 := &t2 { Field1: t1.Field1, }
     return ob2
}

You can try encoding/json to marshal and unmarshal the structs, as long as they have the same fields (with json:"name") and the same basic types.

package main

import (
    "encoding/json"
    "fmt"
)

type common struct {
    INT int
}

type A struct {
    XX  []int
    ZZ  []common
    T_T int `json:"qaq"`
}

type B struct {
    XX  []int
    ZZ  []common
    QAQ int32 `json:"qaq"`
}

func main() {
    a := A{
        XX: []int{1, 2, 3},
        ZZ: []common{
            common{0},
            common{1},
        },
        T_T: 5,
    }

    bs, _ := json.Marshal(a)
    b := new(B)
    json.Unmarshal(bs, b)
    fmt.Printf("a: %+v
", a)
    fmt.Printf("b: %+v
", *b)

}
➜  convert go run main.go
a: {XX:[1 2 3] ZZ:[{INT:0} {INT:1}] T_T:5}
b: {XX:[1 2 3] ZZ:[{INT:0} {INT:1}] QAQ:5}