Reputation: 724
There are two code samples as follows.
Sample 1:
package main
import "fmt"
type Dat struct {
Num int
}
func (d *Dat) Fn1a(i int) {
d.Num = i
}
func (d *Dat) Fn2a() {
d.Num++
}
func main() {
var d Dat
d.Fn1a(1)
d.Fn2a()
fmt.Println(d)
}
Sample 2:
package main
import "fmt"
type Dat struct {
Num int
}
func Fn1b(i int) *Dat {
d := &Dat{i}
return d
}
func (d *Dat) Fn2b() *Dat {
d.Num++
return d
}
func main() {
d := Fn1b(1).Fn2b()
fmt.Println(d)
}
Both samples output the same results.
My question is about the difference between these samples. I could notice the following difference.
Although in Sample 1, type Dat struct
can be changed to type dat struct
, in Sample 2, when type Dat struct
is changed to type dat struct
, golint shows a warning: exported func Fn1b returns unexported type *main.dat, which can be annoying to use
. So in Sample 1, dat
can be used directly as a struct
without being public.
Are there any other differences? For example, which is better?
Thank you so much for your time and advices. And I'm sorry for my immature question.
Upvotes: 2
Views: 570
Reputation: 5914
There are some different topics inside your question:
1) Exported and unexported types
If you have a function, which is exported and that function returns an unexported type this will cause to an error, when you call that function outside of your package.
So let's say that it is not allowed to make your type Dat
unexported.
2) Which solution is better?
That depends on, but at all it would be sample 2. You see how much cleaner your main function is. If your struct will be more complicated you can do some stuff there. For example your struct has a parameter which is a map you need to initialize that map by using make()
. In sample 1 you need to do this every time you create a new Dat type.
Normally you would call that function NewDat()
. If you always use that function when creating a new Dat variable that makes your code also more flexible for changes.
Upvotes: 1