将一个结构分配给“结构相同”类型的其他结构

My problem is like this: I have a MyMail package which provides a function SendMail(MyMail.Mail) to other packages. MyMail uses the package LowLevelMail and its function Send(LowLevelMail.Mail) to actually send Mails. MyMail.Mail and LowLevelMail.Mail are identical in the sense that they define the "same struct" (i.e. equally named and typed fields).

SendMail(m MyMail.Mail) has to convert m to LowLevelMail.Mail before using Send(LowLevelMail.Mail. newmail := LowLevelMail.Mail(m) won't work. But this could be possible as the compiler should be able to see that the fields of the two structs are identical. Maybe it's not a good idea to support this because of not exported fields.

1) Can I somehow assign m to newmail without doing it all by hand (and without losing all type safety?)? The by hand method would cause some pain (the struct does not solely consist of simple types which can be assigned to the other struct's).

2) Is there a better solution to the whole problem (i.e. "I don't want to use other packages' types in my API because I don't want my packages' clients to depend on a foreign API. This foreign API may change or I might decide at some point to not use it any more.").

Update: I missed an important point: LowLevelMail.Mail has a field of type LowLevelMail.Address which also is "redefined" in MyMail as MyMail.Address.

This works :

type T1 struct {
    a int
    b string
}
type T2 struct {
    a int
    b string
}
func main() {
    t1 := T1{2, "test"}
    t2 := T2(t1)
    fmt.Println(t2)
}

Isn't it what you're looking for ?

If your question is about how to do this when T1 and T2 are in different packages and don't export their fields, well, allowing this would simply nullify the privacy of those fields so of course that's not possible.

Your problem seems to be something like this:

package lowlevelmail

type Mail struct { P int; p int}

func Send(m Mail) { }

and

package mymail

import "lowlevelmail"

type Mail lowlevelmail.Mail

func Send(m Mail) { lowlevelmail.Send(lowlevelmail.Mail(m)) }

and

package main

import "mymail"

func main() {var m mymail.Mail; mymail.Send(m)}