Is it considered bad style to return an unexported type from an exported function?
When I've used it, I mostly find it just creates problems.
A better question might be: when is it a good idea to return an unexported type from an exported function.
I would say there's nothing wrong with returning an unexported variable from an exported function. That's what an accessor is by definition.
That said, I would only do that in the case where there was some logic that needed to occur every time the unexported variable needed to be accessed.
EDIT: I hope I understand your clarified question.
If you have an unexported type user struct{}
and you return it with NewUser()
, would that fit your use case? If so, then that is a factory design pattern and is useful in Go if you do not want a 3rd party developer to directly create a user
type object. That way, your "constructor" or "factory" is the only place to get new instances.
So, is it "bad style"? I'd say it depends on what challenge needs to be overcome.
Golang's linters return a warning when you return an unexported type, so I'd say though it's technically possible it's also to be discouraged. 1
One reason is that some code that receives the unexported type cannot save it (iirc without downgrading to interface{}
).
eg:
package me
type me string
func NewMe() me {
return "me"
}
// in main.go
package main
type eff struct {
m *me.me // <-- cant do this
}