将一个结构体分配给另一个“结构相同”的结构体类型

huangapple go评论79阅读模式
英文:

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.

  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.

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

huangapple
  • 本文由 发表于 2012年9月14日 15:58:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/12420321.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定