我想写一个协议测试。我目前的想法是定义一系列步骤。每个步骤都包含一个
Trigger
和 Expectation
- 例如触发MsgA
并期待MsgB
.
type Series struct {
Steps []Step
}
我不喜欢这个的是
Series
不是明确的:我必须按顺序创建切片,然后希望它永远不会搞砸,并依赖它,或者 sort
它和然后必须实现排序功能,这是完全没有必要的。
什么是正式定义
Series
,并以这种方式使其明确化的好设计?
我现在最好的想法是创建一个带有
int
索引的地图:
type Series struct {
Steps map[int]Step
}
series := Series{
Steps: map[int]Step{
0: Step{},
1: Step{},
2: Step{},
...
}
}
另一个选择是为自己建立一个链表。
go
没有实现(afaik)。不得不为此自己建造一个感觉很奇怪。但是这样的解决方案也会稍微放松显式特征:基本上你总是必须浏览链表才能获得整个序列(例如“什么是第 4 步”)。
不使用地图,您仍然可以使用切片并使用keyedcomposite literal:
var steps = []Step{
0: Step{},
1: Step{},
...
}
中有详细说明
CompositeLit = LiteralType LiteralValue . LiteralType = StructType | ArrayType | "[" "..." "]" ElementType | SliceType | MapType | TypeName [ TypeArgs ] . LiteralValue = "{" [ ElementList [ "," ] ] "}" . ElementList = KeyedElement { "," KeyedElement } . KeyedElement = [ Key ":" ] Element . Key = FieldName | Expression | LiteralValue . FieldName = identifier . Element = Expression | LiteralValue .
如您所见,
KeyedElement
可能包含可选的Key ":"
部分。
... 键被解释为结构文字的字段名,数组和切片文字的索引,以及映射文字的键。
请注意,您可以混合键控和“非键控”元素,它们不必是连续的:
type Step struct{}
var steps = []*Step{
0: &Step{},
1: &Step{},
&Step{}, // implicit index: 2
10: &Step{},
}
fmt.Println(steps)
上面的输出(在Go Playground上试试):
[0x559008 0x559008 0x559008 <nil> <nil> 0x559008]
他们的钥匙也可能“乱序”,这意味着这也是有效的:
var steps = []*Step{
5: &Step{},
0: &Step{},
1: &Step{},
&Step{}, // implicit index: 2
}
这输出相同。在 Go Playground 上试试吧。如果切片文字中缺少键,则索引将为前一个索引 + 1。