[英]Conditional/optional fields in struct type
我有一個這樣的Node
結構類型:
package tree
// Enum for node category
type Level int32
const (
Leaf Level = iota + 1
Branch
Root
)
type Node struct {
Children []*Node
Parent *Node
X float32
Y float32
Z float32
Dim float32
Category Level
LeafPenetration float32 // Needed only if category is "Leaf"
RootPadDim float32 // Needed only if category is "Root"
}
我有兩個Node
字段,它們是可選的,僅根據category
字段需要:
leafPenetration float32 // Needed only if category is "Leaf"
rootPadDim float32 // Needed only if category is "Root"
當前的Node
實現是否正常? 結構類型中此類可選/條件字段的最佳實踐是什么?
默認情況下,字段初始化為類型的零值——在float32
的情況下,它是0
。 為避免這種情況,通常對可選字段使用指針,例如:
type Node struct {
Children []*Node
Parent *Node
X float32
Y float32
Z float32
Dim float32
Category Level
// Optional fields
LeafPenetration *float32 // Needed only if category is "Leaf"
RootPadDim *float32 // Needed only if category is "Root"
}
指針字段將默認為nil
。
我最終使用了一種非常簡化的方法:
package tree
// Enum for node category
type Level int32
const (
Leaf Level = iota + 1
Branch
Root
)
type Node struct {
Category Level
Parent *Node
X float32
Y float32
Z float32
Dim float32
RootT float32 // Root thickness
RootD float32 // Root diameter
RootBR float32 // Root bezel ratio of top-bottom, i.e. top D is larger by this much
LeafP float32 // Leaf penetration
}
func NewNode(cat Level, parent *Node, x, y, z, dim float32) *Node {
n := &Node{
Category: cat,
Parent: parent,
X: x,
Y: y,
Z: z,
Dim: dim,
}
switch n.Category {
case Leaf:
n.LeafP = float32(0.3)
case Root:
n.RootT = float32(2)
n.RootD = float32(30)
n.RootBR = float32(1.08)
}
return n
}
遵循這個指南是個好主意嗎?
例如具有此Node
類型:
package tree
// Enum for node category
type Level int32
const (
Leaf Level = iota + 1
Branch
Root
)
type Node struct {
Children []*Node
Parent *Node
X float32
Y float32
Z float32
Dim float32
Category Level
// https://github.com/uber-go/guide/blob/master/style.md#functional-options
Opts []Option
}
實現這樣的選項:
type options struct {
penetration float32 // Needed only if category is "Leaf"
base float32 // Needed only if category is "Root"
}
type Option interface {
apply(*options)
}
// penetration option
type penetrationOption float32
func (p penetrationOption) apply(opts *options) {
opts.penetration = float32(p)
}
func WithPenetrationOption(p float32) Option {
return penetrationOption(p)
}
// base option
type baseOption float32
func (b baseOption) apply(opts *options) {
opts.base = float32(b)
}
func WithBaseOption(b float32) Option {
return baseOption(b)
}
使用上述方法,實現變得過於復雜。 但是,它可以在未來進一步擴展。 雖然不確定它的價值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.