Go没有工会。但是工会在很多地方都是必要的。XML过度使用联合或选择类型。我试图找出答案,这是解决缺少的工会的首选方法。作为一个例子,我试图写Go代码对于非终端Misc
在XML标准,其可以是一个注释,一个处理指令或白空间。
为这三种基本类型编写代码非常简单。它们映射到字符数组和结构。
type Comment Chars
type ProcessingInstruction struct {
Target *Chars
Data *Chars
}
type WhiteSpace Chars
但是,当我完成联合的代码时,它变得with肿了许多冗余功能。显然必须有一个容器结构。
type Misc struct {
value interface {}
}
为了确保容器仅包含三个允许的类型,我将值设为私有,并且必须为每种类型编写一个构造函数。
func MiscComment(c *Comment) *Misc {
return &Misc{c}
}
func MiscProcessingInstruction (pi *ProcessingInstruction) *Misc {
return &Misc{pi}
}
func MiscWhiteSpace (ws *WhiteSpace) *Misc {
return &Misc{ws}
}
为了能够测试联合的内容,有必要编写三个谓词:
func (m Misc) IsComment () bool {
_, itis := m.value.(*Comment)
return itis
}
func (m Misc) IsProcessingInstruction () bool {
_, itis := m.value.(*ProcessingInstruction)
return itis
}
func (m Misc) IsWhiteSpace () bool {
_, itis := m.value.(*WhiteSpace)
return itis
}
为了获得正确键入的元素,有必要编写三个getter。
func (m Misc) Comment () *Comment {
return m.value.(*Comment)
}
func (m Misc) ProcessingInstruction () *ProcessingInstruction {
return m.value.(*ProcessingInstruction)
}
func (m Misc) WhiteSpace () *WhiteSpace {
return m.value.(*WhiteSpace)
}
之后,我可以创建一个Misc
类型数组并使用它:
func main () {
miscs := []*Misc{
MiscComment((*Comment)(NewChars("comment"))),
MiscProcessingInstruction(&ProcessingInstruction{
NewChars("target"),
NewChars("data")}),
MiscWhiteSpace((*WhiteSpace)(NewChars(" \n")))}
for _, misc := range miscs {
if (misc.IsComment()) {
fmt.Println ((*Chars)(misc.Comment()))
} else if (misc.IsProcessingInstruction()) {
fmt.Println (*misc.ProcessingInstruction())
} else if (misc.IsWhiteSpace()) {
fmt.Println ((*Chars)(misc.WhiteSpace()))
} else {
panic ("invalid misc");
}
}
}
您会看到很多看起来几乎相同的代码。对于任何其他工会也是如此。所以我的问题是:是否有任何方法可以简化Go语言中处理工会的方式?
Go声称通过消除冗余来简化编程工作。但是我认为上面的例子显示了完全相反的情况。我有想念吗?
这是完整的示例:http :
//play.golang.org/p/Zv8rYX-aFr
似乎您在问这是因为您想要类型安全,所以我首先认为您的初始解决方案已经不安全了
func (m Misc) Comment () *Comment {
return m.value.(*Comment)
}
如果您之前没有检查IsComment
过,将会感到恐慌。因此,与Volker提出的类型开关相比,该解决方案没有任何好处。
由于要对代码进行分组,因此可以编写一个确定Misc
元素是什么的函数:
func IsMisc(v {}interface) bool {
switch v.(type) {
case Comment: return true
// ...
}
}
但是,那也不会给您带来编译器类型检查。
如果您希望能够Misc
由编译器识别某些内容,则应考虑创建一个将某些内容标记为的接口Misc
:
type Misc interface {
ImplementsMisc()
}
type Comment Chars
func (c Comment) ImplementsMisc() {}
type ProcessingInstruction
func (p ProcessingInstruction) ImplementsMisc() {}
这样,您可以编写仅处理杂项的函数。对象并稍后决定要在这些函数中真正要处理的内容(注释,说明等)。
如果您想模仿工会,那么据我所知,这是您写作的方式。
问题内容: 我刚开始学习Go,并通读现有代码以学习“其他人的做法”。在这种情况下,遍历使用go“工作区”,尤其是与项目依赖关系有关的地方。 在处理各种Go项目时,使用一个或多个Go工作区(即$ GOPATH的定义)的常见(或存在)最佳实践是什么?我应该期望有一个类似于我所有项目的中央代码存储库的Go工作区,还是在我处理这些项目时都明确将其分解并设置$ GOPATH(有点像python) virtu
问题内容: 和之间的实际区别是什么? 假设我希望用户会话在闲置15分钟后无效(而不是在第一次打开后15分钟内无效)。其中哪一项对我有帮助? 我也知道我可以这样做,可以将用户的Cookie设置为在一定时间内过期。但是,cookie过期与服务器端的实际会话过期是不相同的。Cookie过期后,这还会删除会话吗? 我的另一个解决方案是 对每个请求都很简单 ,然后将会话与当前时间进行比较,然后基于该时间删除
我目前正在使用带有mgo lib的mongoDB作为Web应用程序,但我不确定我使用它的方式是否是好的。 我初始化db会话并创建获取集合和文档值的变量,因此当我需要查询集合时,我使用该变量进行查询。 像这样: 那么,有没有一个最佳实践,或者这一个很好。。?谢谢
这里有些给使用和编写 Ansible playbook 的贴士. 你能在我们的 ansible-example repository.找到展示这些最佳实践的 playbook 样例.(注意: 这些示例用的也许不是最新版的中所有特性,但它们仍旧是极佳的参考.) Topics 最佳实践 接下来的章节将向你展示一种组织 playbook 内容方式. 你对 Ansible 的使用应该符合你的需求而不是我们
处理后台任务与常规调用方法有很大的不同。本指南旨在帮助让您的后台任务平稳有效地运行。本文基于 这篇博客文章。 使任务参数小而简单 方法(任务)在调用之前会被序列化。使用 TypeConverter 类将参数转换为 JSON 字符串。如果您有复杂的实体和 / 或大对象; 包括数组,最好将它们放入数据库,然后只将其标识 (id) 传递给后台任务。 错误例子: public void Method(En
VR设计 VR设计不同于平面体验设计。作为一种新的媒介,有新的最佳实践需要遵循,特别是保持用户的舒适性和存在性。这在如下指南中已经写得很透彻了: Oculus VR最佳实践 Leap Motion VR最佳实践指南 一些值得注意的事情: 公共的金科玉律是永远不要意外地把相机控制权从用户手中剥夺。 单位(比如对于位置)应该考虑使用米(m)。这是因为WebVR API以米为单位返回姿势数据,进而传送给