一个类型时应该是包含另一种类型的结构体,并且当应该它只是“扩展”(?),该类型?(When shou

2019-08-06 03:55发布

目前,我正在做学习围棋罗莎琳德问题 (基本上是相关的代码katas一堆生物信息学)。

我目前较一类型的DNA链:

type DNAStrand struct {
    dna byte[]
}

我最初的原因是封装字节片,所以我会知道它只是代表所含核苷酸字节: 'A', 'C', 'G', 'T' 。 我意识到,这显然不是guarateed因为我可以简单地这样做:

DNAStrand{[]byte("foo bar")}

而且不再有我的DNA链包含有从那些四个字节唯一元素的字节数组任何保证。

由于我的结构只包含一个字节数组,岂不是更好/更ideomatic做:

type DNAStrand []byte

或者是更好地让类型包含DNA链? 是否有当为使用这两种方法的拇指任何规则?

Answer 1:

结构与零个域都得心应手。 与许多领域结构都得心应手,甚至更多。 恰好与一个场结构是有点特别,我想不出一个合理的“好”的情况下使用它们的 - 即使它们经常可以看到“野生”。 就我个人来说,不使用它们。

无论如何,如果你真的需要有关更紧/防弹安全DNAStrand切片内容-然后就可以使用单场结构和定义的参数检查此/此类命名类型setter方法。

在这种情况下,如果定义是后来从一些其他的封装中使用,有使用没有办法,模包不安全 ,规避检查,并获得等同于你的结果DNAStrand{[]byte("foo bar")}例子。



Answer 2:

以你的具体的例子,我可能会做这样的事情:

type neucleotide char // unexported type users can't construct their own.

type DNAStrand []neucleotide // because users can't construct their own
                             // nucleotides they also can't construct their
                             // own DNAStrands.

const (
  // These are exported values so they can use these nucleotides to construct a
  // DNAStrand with.
  A nucleotide = 'A'
  C nucleotide = 'C'
  G nudleotide = 'G'
  T nucleotide = 'T'
)

// This function allows them to actually construct a DNAstrand with a list of
//  nucleotides from the constants above.
func New(nts ...nucleotide) DNAStrand {
    return nts
}

由于核苷酸类型不导出用户无法构建自己的。 你为他们提供的只允许情况下,在出口consts所以没有用户可以提供自己的新的核苷酸。



Answer 3:

我会用type DNAStrand []byte ,因为它很简单,因为我可以在其上使用正则表达式。 我可能会使用检查每一个字节是ACGT虽然一个初始化函数。

var validDNAStrandPat = regexp.MustCompile("[ACTG]*")

func DNAStrandForString(s string) DNAStrand {
    if !validDNAStrandPat.Match(s) {
        panic("Invalid DNA Strand.")
    }
    return DNAStrand([]byte(s))
}


文章来源: When should a type be a struct containing another type and when should it just “extend”(?) that type?
标签: types struct go