目前,我正在做学习围棋罗莎琳德问题 (基本上是相关的代码katas一堆生物信息学)。
我目前较一类型的DNA链:
type DNAStrand struct {
dna byte[]
}
我最初的原因是封装字节片,所以我会知道它只是代表所含核苷酸字节: 'A', 'C', 'G', 'T'
。 我意识到,这显然不是guarateed因为我可以简单地这样做:
DNAStrand{[]byte("foo bar")}
而且不再有我的DNA链包含有从那些四个字节唯一元素的字节数组任何保证。
由于我的结构只包含一个字节数组,岂不是更好/更ideomatic做:
type DNAStrand []byte
或者是更好地让类型包含DNA链? 是否有当为使用这两种方法的拇指任何规则?
结构与零个域都得心应手。 与许多领域结构都得心应手,甚至更多。 恰好与一个场结构是有点特别,我想不出一个合理的“好”的情况下使用它们的 - 即使它们经常可以看到“野生”。 就我个人来说,不使用它们。
无论如何,如果你真的需要有关更紧/防弹安全DNAStrand
切片内容-然后就可以使用单场结构和定义的参数检查此/此类命名类型setter方法。
在这种情况下,如果定义是后来从一些其他的封装中使用,有使用没有办法,模包不安全 ,规避检查,并获得等同于你的结果DNAStrand{[]byte("foo bar")}
例子。
以你的具体的例子,我可能会做这样的事情:
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所以没有用户可以提供自己的新的核苷酸。
我会用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?