簡體   English   中英

結構類型中的條件/可選字段

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM