精校:10.2-10.4

This commit is contained in:
Unknwon
2015-08-16 16:52:01 +08:00
parent b0b3812a9d
commit 55ac71730e
6 changed files with 49 additions and 35 deletions

View File

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