golang:如何定义一系列步骤

golang: How to define a sequence of steps

提问人:transient_loop 提问时间:4/18/2023 最后编辑:iczatransient_loop 更新时间:4/18/2023 访问量:115

问:

我想编写一个协议测试。我目前的想法是定义一系列步骤。每个步骤都包含一个 和 - 例如 trigger 和 expect。TriggerExpectationMsgAMsgB

type Series struct {
  Steps []Step
}

我不喜欢这一点的是,它不是明确的:我必须按顺序创建切片,然后希望它永远不会搞砸,并依赖它,或者它,然后必须实现排序函数,这是完全没有必要的。Seriessort

什么是好的设计来正式定义 ,并以这种方式使其显式?Series

我现在最好的想法是创建一个带有索引的地图:int

type Series struct {
   Steps map[int]Step
}

series := Series{
   Steps: map[int]Step{
     0: Step{},
     1: Step{},
     2: Step{},
     ...
   }
}

另一种选择是为自己建立一个链表。 没有实现 (AFAIK)。为此必须自己建造一个感觉很奇怪。但这样的解决方案也会稍微失去显式功能:基本上,您始终必须浏览链表才能获得整个序列(例如,“什么是第 4 步”)。go

list go slice sequence 复合文字

评论

0赞 icza 4/18/2023
为此,可以使用键控复合文本:var steps = []Step{0: Step{}, 1: Step{}, ...}
0赞 transient_loop 4/18/2023
神圣的@#$@!@icza请提供此解决方案,我什至不知道这是可能的!!我现在工作了好几年了......真是太可惜了。go

答:

3赞 icza 4/18/2023 #1

您仍然可以使用切片并使用键控复合文本,而不是使用映射:

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 .

如您所见,可能包含可选部件。KeyedElementKey ":"

...该键被解释为结构文本的字段名称、数组和切片文本的索引以及映射文本的键。

请注意,您可以混合使用键控元素和“非键控”元素,它们不必是连续的。此外,如果切片文本中缺少键,则索引将是前一个索引 + 1。

type Step struct{}

var steps = []*Step{
    0:       &Step{},
    1:       &Step{},
    &Step{}, // implicit index: 2
    5:       &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 上尝试一下。