Go は、型エイリアス (エイリアス型) と構造体を通じてユーザー定義型をサポートします。
構造体は複合型です。各属性が独自の型と値を持つ一連の属性で構成される型を定義する必要がある場合は、データをまとめて収集する構造体を使用する必要があります。
構造体も値型であるため、新しい関数を使用して
構造体型を構成するデータがフィールドになります。各フィールドには型と名前があり、構造内でフィールド名は一意である必要があります。
1. 構造体の定義
構造体を定義する一般的な方法は次のとおりです:
type identifier struct { field type1 field type2}
type T struct { a, b int} も正当な構文です。単純な構造に適しています。
構造内のフィールドには、field1、field2 などの名前が付いています。フィールドがコード内で使用されない場合は、 , 次に、_ という名前を付けることができます。
構造体タイプとフィールドの命名は可視性ルールに従うため、構造体タイプの一部のフィールドはエクスポートされ、その他のフィールドはエクスポートされない場合があります。
構造体のフィールドは、構造体自体を含む任意の型にすることができ、関数やインターフェイスにすることもできます。次のように構造体型の変数を宣言し、そのフィールドに値を割り当てることができます。
var s T s.a = 5 s.b = 8
配列も構造体型と見なすことができますが、名前付きフィールドの代わりに添字を使用します
2 番目、初期化
#方法 1: var を通じて構造体を宣言する
Go 言語で変数が宣言されると、システムはそのデフォルト値を自動的に初期化します (たとえば、int は 0 に初期化され、ポインタは nil になります)。
var 宣言は構造型データにもメモリを割り当てるため、前のコードのように var s T を宣言した後、そのフィールドに値を直接割り当てることができます。
方法 2: を使用します。 new
new 関数を使用して、新しい構造体変数にメモリを割り当てます。この関数は、割り当てられたメモリへのポインタを返します: var t *T = new(T)。
type struct1 struct { i1 int f1 float32 str string}func main() { ms := new(struct1) ms.i1 = 10 ms.f1 = 15.5 ms.str= "Chris" fmt.Printf("The int is: %d\n", ms.i1) fmt.Printf("The float is: %f\n", ms.f1) fmt.Printf("The string is: %s\n", ms.str) fmt.Println(ms) }
オブジェクト指向言語と同じように、ドット演算子を使用してフィールドに値を割り当てることができます: structname.fieldname = value。
同様に、ドット演算子を使用して構造体フィールドの値を取得できます: structname.fieldname。
方法 3: リテラルを使用する
type Person struct { name string age int address string } func main() { var p1 Person p1 = Person{"lisi", 30, "shanghai"} //方式A p2 := Person{address:"beijing", age:25, name:"wangwu"} //方式B p3 := Person{address:"NewYork"} //方式C }
(方法 A) では、構造内でフィールドが定義されている順序で値を指定する必要があります。 (方法 B) 値の前にフィールド名とコロンを追加します。この方法では、値の順序は一貫している必要はなく、(方法 C) と同様に一部のフィールドは無視できます。
上記の 3 つの方法に加えて、次のような、より短くより一般的な構造エンティティの初期化方法があります。
ms := &Person{"name", 20, "bj"} ms2 := &Person{name:"zhangsan"}
&person{a, b, c} は省略形です。最下層は引き続き new() を呼び出しますが、値の順序はフィールドの順序で書き込む必要があります。値の前にフィールド名とコロンを追加することによっても書き込むことができます (メソッド B とメソッドを参照)上記C)。
式 new(Type) と &Type{} は同等です。
3. いくつかの初期化方法の違い
これまで、構造体を初期化する 3 つの方法について学習しました。
var t T を使用すると、 t にメモリが割り当てられ、メモリの値がゼロになりますが、このときの t の型は T新しいキーワード t := new(T) を使用すると、変数t は T へのポインタです。メモリ レイアウトから、これら 3 つの初期化方法の違いがわかります。Use var ステートメント:new を使用して初期化します: 構造リテラルを使用して初期化します: 具体的な例を見てみましょう:
//第一种,在Go语言中,可以直接以 var 的方式声明结构体即可完成实例化 var t T t.a = 1 t.b = 2 //第二种,使用 new() 实例化 t := new(T) //第三种,使用字面量初始化 t := T{a, b} t := &T{} //等效于 new(T)出力:
package main import "fmt" type Person struct { name string age int } func main() { var p1 Person p1.name = "zhangsan" p1.age = 18 fmt.Printf("This is %s, %d years old\n", p1.name, p1.age) p2 := new(Person) p2.name = "lisi" p2.age = 20 (*p2).age = 23 //这种写法也是合法的 fmt.Printf("This is %s, %d years old\n", p2.name, p2.age) p3 := Person{"wangwu", 25} fmt.Printf("This is %s, %d years old\n", p3.name, p3.age) }上記の例の 2 番目のケースでは、p2 はポインター型ですが、それでも p2.age = 23 のようにすることができます。代入の場合、次のようにする必要はありません。 C のように -> 演算子を使用すると、Go が自動的に変換します。 * 演算子を使用して、最初にポインターが指すコンテンツを取得し、それを (*p2).age = 23 のように割り当てることもできることに注意してください。
構造体のメモリレイアウト
Go 语言中,结构体和它所包含的数据在内存中是以连续块的形式存在的,即使结构体中嵌套有其他的结构体,这在性能上带来了很大的优势。不像 Java 中的引用类型,一个对象和它里面包含的对象可能会在不同的内存空间中,这点和 Go 语言中的指针很像。
下面的例子清晰地说明了这些情况:
type Rect1 struct {Min, Max Point } type Rect2 struct {Min, Max *Point }
更多go语言知识请关注PHP中文网go语言教程栏目。
以上がGo 言語の構造と初期化のグラフィックとテキストの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。