ストラクチャーファクトリー
Go 言語は、オブジェクト指向プログラミング言語のようなコンストラクター メソッドをサポートしていませんが、Go では「コンストラクター ファクトリ」メソッドを簡単に実装できます。便宜上、ファクトリは通常、型に対して定義され、慣例により、ファクトリの名前は new または New で始まります。次のファイル構造タイプが定義されているとします。
type File struct {
fd int // 文件描述符
name string // 文件名
}
以下は、この構造体型のファクトリ メソッドで、構造体インスタンスへのポインターを返します。
func NewFile(fd int, name string) *File {
if fd < 0 {
return nil
}
return &File{fd, name}
}
次のように呼び出します。
f := NewFile(10, "./test.txt")
Go 言語では、コンストラクターを単純に実装するために、上記のようにファクトリ メソッドで初期化を使用することがよくあります。
File が構造体型の場合、式 new(File) と &File{} は等価です。
これは、ほとんどのオブジェクト指向プログラミング言語の不器用な初期化 ( File f = new File(...) ) と比較できます。
クラスベースの OOP 言語のように、ファクトリは型のオブジェクトをインスタンス化すると言えます。
構造体型 T のインスタンスが使用するメモリ量を知りたい場合は、size := unsafe.Sizeof(T{}) を使用できます。
ファクトリ メソッドの使用を強制する方法
可視性ルールを適用することで、 セクション 4.2.1、セクション 9.5 を参照してください。オブジェクト指向言語のように、新しい関数の使用を禁止し、ユーザーにファクトリ メソッドの使用を強制し、型を非公開にすることができます。
type matrix struct {
...
}
func NewMatrix(params) *matrix {
m := new(matrix) // 初始化 m
return m
}
他のパッケージでファクトリ メソッドを使用する:
package main
import "matrix"
...
wrong := new(matrix.matrix) // 编译失败(matrix 是私有的)
right := matrix.NewMatrix(...) // 实例化 matrix 的唯一方式
map と struct vs new() と make()
2 つの組み込み関数 new と make については、 セクション7.2.4でスライスの例を使用してすでに説明しました。
make()
これまでのところ、使用できる 3 つのタイプのうち 2 つを見てきました 。
slices / maps / channels(见第 14 章)
次の例は、マップでの new と make の使用の違いと、考えられるエラーを示しています。
例 10.4 new_make.go (コンパイルしない)
type Foo map[string]string
type Bar struct {
thingOne string
thingTwo int
}
func main() {
// OK
y := new(Bar)
(*y).thingOne = "hello"
(*y).thingTwo = 1
// NOT OK
z := make(Bar) // 编译错误:cannot make type Bar
(*z).thingOne = "hello"
(*z).thingTwo = 1
// OK
x := make(Foo)
x["x"] = "goodbye"
x["y"] = "world"
// NOT OK
u := new(Foo)
(*u)["x"] = "goodbye" // 运行时错误!! panic: assignment to entry in nil map
(*u)["y"] = "world"
}
struct 変数を make() しようとするとコンパイル エラーがスローされますが、これはそれほど悪いことではありませんが、マップを new() してデータを入力しようとすると、ランタイム エラーがスローされます。new(Foo) は nil へのポインタを返すため、メモリはまだ割り当てられていません。そのため、地図を使用するときは注意してください。