* 校验ch10.2

This commit is contained in:
leisore
2015-07-04 15:45:26 +08:00
parent 1fa82a86c7
commit dc9648b3f7

View File

@@ -2,7 +2,7 @@
## 10.2.1 结构体工厂
Go语言不支持面向对象编程语言中那样的构造子,但是可以很容易的使用Go实现“构造子工厂“函数。为了方便常会为一个类型定义一个工厂,按照约定工厂的名字以new或New开头。假设定义了如下的File结构体类型
Go语言不支持面向对象编程语言中那样的构造子方法,但是可以很容易的Go实现“构造子工厂“方法。为了方便常会为类型定义一个工厂,俺惯例,工厂的名字以new或New开头。假设定义了如下的File结构体类型
```go
type File struct {
@@ -14,7 +14,7 @@ type File struct {
下面是这个结构体类型对应的工厂方法,它返回一个指向结构体实例的指针:
```go
func NewFile(fd int, name string) *File {
func NewFile(fd int, name string) *File {
if fd < 0 {
return nil
}
@@ -22,21 +22,21 @@ func NewFile(fd int, name string) *File {
return &File(id, name)
}
```
调用它的例子`f := NewFile(10, "./test.txt")`
然后这样调用它:`f := NewFile(10, "./test.txt")`
在Go语言中常常像上面这样在工厂方法里使用初始化简便的实现构造子。
在Go语言中常常像上面这样在工厂方法里使用初始化简便的实现构造子。
如果`File`是一个结构体类型,那么表达式`new(File)``&File{}`是等价的。
可以和大多数面向对象编程语言中笨拙的初始化方式做个比较:`File f = new File(...)`
可以和大多数面向对象编程语言中笨拙的初始化方式做个比较:`File f = new File(...)`
我们可以说是工厂实例化了类型的一个对象就像在基于类的OO语言中那样。
如果想知道结构体类型T的一个实例占用了多少内存可以使用`size := unsafe.Sizeof(T{})`
*如强制使用工程函数*
**如强制使用工厂方法**
通过使用可见性规则参考4.2.19.5就可以禁止使用new函数强制用户使用工厂方法从而有效地使类型变成私有的就像在OO语言中那样。
通过用可见性规则参考4.2.19.5就可以禁止使用new函数强制用户使用工厂方法从而使类型变成私有的就像在OO语言中那样。
```go
type matrix struct {
@@ -44,7 +44,7 @@ type matrix struct {
}
func NewMatrix(params) *matrix {
m := new(matrix) // 初始化m
m := new(matrix) // 初始化m
return m
}
```
@@ -59,15 +59,15 @@ func NewMatrix(params) *matrix {
right := matrix.NewMatrix(...) // 实例化matrix的唯一方式
```
## 10.2.2 map和struct vs new()和make()再探
## 10.2.2 map和struct vs new()和make()
new和make这两个内置函数已经在[7.2.4](7.2.md)节通过切片的例子说明过一次。
现在为止我们已经见到了可以使用make()的三种类型其中两个:
现在为止我们已经见到了可以使用make()的三种类型中的其中两个:
slices / maps / channels见第14章
使用下面的例子来说明在映射上使用它们的区别和可能的发生的错误:
下面的例子来说明在映射上使用new和make的区别以及可能的发生的错误:
Listing 10.4—new_make.go不能编译
@@ -103,7 +103,7 @@ func main() {
}
```
试图make()一个结构体变量会引发一个编译错误这不是太糟糕但是new()一个映射并试图使用数据填充它将会引发运行时错误new(Foo)返回一个指向nil的指针它尚未被分配内存。所以在使用map时要特别谨慎。
试图make()一个结构体变量,会引发一个编译错误,这不是太糟糕但是new()一个映射并试图使用数据填充它,将会引发运行时错误! 因为new(Foo)返回的是一个指向nil的指针它尚未被分配内存。所以在使用map时要特别谨慎。
## 链接
- [目录](directory.md)