假设有如下结构体定义
```
type Author struct {
name string
}
type Publisher struct {
name string
}
type Category struct {
name string
}
type BookBase struct {
name string
page int
}
type Book struct {
base BookBase
author Author
publisher Publisher
category Category
}
```
如果想要`New`一个`Book`类型的`struct`, 有如下两种方式
方式一:
```
func New(author Author, publisher Publisher, category Category, base BookBase) Book {
return Book{
base: base,
author: author,
publisher: publisher,
category: category,
}
}
```
方式二:
```
func New(authorName string, publisherName string, category string, id int, title string, content string) Book {
return Book{
base:BookBase{
articleId: id,
title:title,
content:content,
},
author:Author{name:authorName},
publisher:Publisher{name:publisherName},
category:Category{name:category},
}
}
```
如果使用**方式一**,客户端代码大概下面这样
```
func main() {
author := Author{name:"小明"}
publisher := Publisher{name:"宇宙出版社"}
category := Category{name:"神经病学"}
base := BookBase{
name:"论大脑的疑难杂症",
page:1000,
}
// new a book
book := New(author, publisher, category, base)
fmt.Println(book)
}
```
如果使用**方式二**,客户端代码大概下面这样
```
func main() {
// new a book
book := New("小明", "宇宙出版社", "神经病学", 1000, "论大脑的疑难杂症")
fmt.Println(book)
}
```
请问哪种`New`更符合Gopher习惯呢?或者是否有其他更好的方式。
完整代码请参考 [Go Playground](https://play.golang.org/p/0SyaZDnRP68)
更多评论
我不太喜欢New函数带很多参数,一般我只传初始化需要的关键参数,New里面一般不做上面那种简单的逐个field赋值,而是初始化map,channel,slice等,以及设置各个field的默认值,在New返回后再逐个设置field,因为这样更清楚是给哪个field赋值
New带多个参数不好的地方就是不知道各个参数对应什么field,以及如果有新的field加入且这个filed只在很少的地方用到的情况下需要修改所有调用New的地方并传入无用的值
实际应用中这种有多个field需要赋值的情况也不会用New来传参,而是从什么数据源unmarshal进来
#2
还有,go里面面向对象继承的关键点在把Book定义成下面这样:
type Book struct {
BookBase
author Author
publisher Publisher
category Category
}
这样Book才有了BookBase的所有方法
#3