Christian
Christian

Reputation: 4255

Assignment of one struct to other struct of "structural identical" type

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.

Upvotes: 2

Views: 390

Answers (2)

peterSO
peterSO

Reputation: 166825

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)}

Upvotes: 1

Denys Séguret
Denys Séguret

Reputation: 382434

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.

Upvotes: 1

Related Questions