为了账号安全,请及时绑定邮箱和手机立即绑定

如何禁止直接结构初始化

如何禁止直接结构初始化

Go
小怪兽爱吃肉 2021-08-23 16:56:03
鉴于 Go 中的以下包,是否可以防止Barwith的直接初始化 Bar{..}而不Bar从包中取消暴露?包bar:package barimport ()type Bar struct {    A string    B string}func NewBar(baz string) Bar{    return Bar{A:baz, B:baz+baz}}包main:package mainimport (    "fmt"    "./bar")func main() {    x := bar.NewBar("sad") //all bars should be created with this    y := bar.Bar{A: "fadss"} //and this should be disallowed    bzzBar(x)    bzzBar(y)}func bzzBar(bzz bar.Bar) { //but I can't do 'Bar -> bar' because I want to use the type    fmt.Println(bzz)}我的直觉说这是不可能的,所以这也是一个有效的答案。
查看完整描述

3 回答

?
忽然笑

TA贡献1806条经验 获得超5个赞

没有办法阻止Bar{}或Bar{A: "foo"}。


要以您想要的方式控制结构,您可以返回一个接口而不是导出结构本身。


给出的例子:


package bar


type Bar interface{

    A() string

    B() string

    // if you need setters

    SetA(string)

    SetB(string)

}


type bar struct {

    a string

    b string

}


func (b *bar) A() string { return b.a }

func (b *bar) B() string { return b.b }


func (b *bar) SetA(val string) { b.a = val }

func (b *bar) SetB(val string) { b.b = val }


func NewBar(baz string) Bar {

    return &bar{a:baz, b:baz+baz}

}


查看完整回答
反对 回复 2021-08-23
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

您可以不Bar导出所有字段并为它们提供 getter 和 setter。这样打包用户仍然可以做一些愚蠢的事情,比如


a := Bar{}

b := Bar{"foo"}

两者都没有或似乎有用(尽管前者可用于创建Bar类似于的空&bytes.Buffer{})。


查看完整回答
反对 回复 2021-08-23
  • 3 回答
  • 0 关注
  • 177 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信