2

I have a private struct (actually more than one, I simplified a bit for this example) which I have a public function on, that satisfies a public interface. This struct is created via a factory method (NewX-style):

package godocprivate

type PublicInterface interface {
    PublicFunction()
}

type privatestruct struct {
}

func NewPublic() *privatestruct {
    ps := &privatestruct{}
    return ps
}

// PublicFunction does something to be documented
func (self *privatestruct) PublicFunction() {
}

I cannot make the factory method return the public interface, because there are other interfaces to be satisfied by the returned value, in my project.

I do want to document PublicFunction() via godoc, but because it is on a private struct, it does not show up:

This is how Godoc of the above looks like

Is there any way, trick, workaround, etc. to make privatestruct.PublicFunction() visible in Godoc?

My actual use case is even more severe: I do have more than one private struct. All of them satisfy PublicInterface, but the inner workings of their respective PublicFunction-implementations differ, hence could their documentations need to be different, too...

Peter Brennan
  • 1,366
  • 12
  • 28

1 Answers1

1

PublicFunction uses PublicStruct whose private fields will be private with private documentation. For example,

package godocprivate

type PublicInterface interface {
    PublicFunction()
}

type privatestruct struct {
}

// PublicStruct is something to be documented except for private fields
type PublicStruct struct {
    privatestruct
}

func NewPublic() *PublicStruct {
    ps := &PublicStruct{}
    return ps
}

// PublicFunction does something to be documented
func (p *PublicStruct) PublicFunction() {
}

When PublicStruct is created it initially has zero values for each field. If that's not enough, introduce a factory boolean. For example,

package godocprivate

type PublicInterface interface {
    PublicFunction()
}

type privatestruct struct {
}

// PublicStruct is something to be documented except for private fields
type PublicStruct struct {
    factory bool
    privatestruct
}

func NewPublic() *PublicStruct {
    ps := &PublicStruct{factory: true}
    return ps
}

// PublicFunction does something to be documented
func (p *PublicStruct) PublicFunction() {
    if !p.factory {
        panic("Use NewPublic")
    }
}
peterSO
  • 158,998
  • 31
  • 281
  • 276
  • Sorry for leaving this important part out: My private struct has an intricate construction process, so I did not want any consumer of the package to be able to circumvent the factory method. Your proposed solution would allow for that. If going that way would be feasible, I could have made privatestruct public in the first place. Or am I missing out on a cool trick here? – Peter Brennan May 07 '15 at 19:37
  • 1
    @PeterHommel: The fields are private, so API clients cannot set them. That means, the only thing that API clients can do if they try and work around your constructor is get a zero value. Who cares? But if you do not like it, then just define a public interface with all of the struct's public methods, and return that instead. – Jean Hominal May 07 '15 at 19:48
  • 1
    However, I would seriously go with simply making a public, all-fields private struct - that seems the most go-like, and is a pattern that appears in the standard library. – Jean Hominal May 07 '15 at 19:50
  • @PeterHommel: See my revised answer. – peterSO May 07 '15 at 19:52
  • @peterSO: Although I am beginning to think that I may be over-encapsulating a bit, your latter solution is really inventive! – Peter Brennan May 07 '15 at 19:59