英文:
Assignment of one struct to other struct of "structural identical" type
问题
我的问题是这样的:我有一个“MyMail”包,它提供一个函数“SendMail(MyMail.Mail)”给其他包使用。 “MyMail”使用“LowLevelMail”包及其函数“Send(LowLevelMail.Mail)”来实际发送邮件。 “MyMail.Mail”和“LowLevelMail.Mail”在定义上是相同的(即具有相同的字段名称和类型)。
在使用“Send(LowLevelMail.Mail)”之前,“SendMail(m MyMail.Mail)”必须将“m”转换为“LowLevelMail.Mail”。 “newmail := LowLevelMail.Mail(m)”不起作用。但是,编译器应该能够看到两个结构体的字段是相同的,所以这可能是可行的。也许不支持这个是一个好主意,因为这样做会导致未导出字段的问题。
1)我是否可以以某种方式将“m”分配给“newmail”,而不是手动完成(并且不会失去所有类型安全性)?手动方法会带来一些麻烦(结构体不仅仅由可以分配给其他结构体的简单类型组成)。
2)是否有更好的解决方案来解决整个问题(即“我不想在我的API中使用其他包的类型,因为我不希望我的包的客户端依赖于外部API。这个外部API可能会发生变化,或者我可能决定在某个时候不再使用它。”)。
更新:我忽略了一个重要的点:LowLevelMail.Mail
有一个类型为LowLevelMail.Address
的字段,在MyMail
中也被“重新定义”为MyMail.Address
。
英文:
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.
-
Can I somehow assign
m
tonewmail
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). -
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
.
答案1
得分: 1
这样可以:
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)
}
这是你要找的吗?
如果你的问题是关于当T1和T2在不同的包中且不导出它们的字段时如何做到这一点,那么允许这样做将简单地使这些字段的私有性失效,所以当然是不可能的。
英文:
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.
答案2
得分: 1
你的问题似乎是这样的:
package lowlevelmail
type Mail struct { P int; p int}
func Send(m Mail) { }
和
package mymail
import "lowlevelmail"
type Mail lowlevelmail.Mail
func Send(m Mail) { lowlevelmail.Send(lowlevelmail.Mail(m)) }
以及
package main
import "mymail"
func main() {var m mymail.Mail; mymail.Send(m)}
英文:
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)}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论