1.定義
構造:
1、複雑なデータ構造の定義からして
複数のフィールドを含むことができる2、構造体(属性)
区別3、構造体のタイプは方法、注意と機能を定義することができます
4、strucr型が値型であります
5、構造体型を入れ子にすることができます
6、全く言語クラスタイプ、唯一のタイプの構造体を行くん
構造体の宣言:
識別子タイプ{構造体は、 入力フィールド1 フィールド2タイプ }
例:
タイプの学生のstruct { 名前の文字列の 年齢int型 スコアのint }
構造体の3つの形式が定義された 三つの方法の初期化
、STUの学生でした
Bは、STU *学生=新(学生)でした
C、VaRのSTU *スチューデント=&学生{}
前記ポインタは答礼訪問、次の形式の構造BとCを指しています。
、stu.Name、stu.Ageとstu.Scoreか(* STU).nameの、(* STU).Ageのような
それは、ポインタの形態である場合、実際には、自動的にアクセスへのポインタの形式に変換し、上記従来の方法でアクセスすることができます
完全な例:
メインパッケージ のインポート( "FMTを" ) 学生のstruct {入力 名文字列 年齢int型 スコアのfloat32 } メインFUNC(){ //声明方式一 のvar STU学生 stu.Name = "華" stu.Age = 18 stu.score = 80 / /声明方式二 VAR STU1 *スチューデント=&学生{ 年齢:20、 名称: "華"、 } //声明方式三 VAR stu3 =学生{ 年齢:20、 名称: "華"、 } fmt.Printf(stu1.Name ) fmt.Printf(stu3.Name) }
構造は、単一のユーザー定義型であり、他の種類はキャストすることはできません
以下のための主要なパッケージ変更 のインポート( "FMT" ) タイプ整数int型の FUNCメイン(){ //それをしないタイプを割り当て、それがどのような型にキャストしなければならない iは整数1000年= VAR fmt.Println(I) VAR J int型= 100 //をiは自己定義型であり、jは、int型のものであるのでときにキャストに割り当て、 J = INT(I)// I jはint型にキャストすることに割り当てられている場合 、I =整数(J)// Jコピーしたい場合、私はInteger型に変換する必要があります fmt.Printlnを(I) fmt.Println(J) }
型が定義されているため、ステュ上記学生の両方が、同じタイプこれら二つのフィールドものとしてではなく、エイリアス関係であります
ファクトリパターン
構造体のgolangは、一般的にこの問題を解決するためにファクトリパターンを使用して、コンストラクタを持っていません
パッケージモデル
タイプの学生構造体{
名前の文字列
年齢はint
}
FUNC NewStudent(名前文字列、年齢はint)*学生{
リターン&学生{//はのインスタンスを作成します
名前:名
年齢:年齢
}
}
パッケージメイン
S:新しい(学生)
S:model.NewStudent(「トニー」、20)
再び
マップ、スライス、チャネルを作成することができます
新しい値型を作成します
ストラクトタグを
私たちは、それぞれのフィールドをstrctタグに相談することができ、タグは反射によって取得することができ、最も一般的なシナリオは、JSONシリアライズとデシリアライズであります
タイプの学生のstruct {
名の文字列には、この欄で説明したように、//、各フィールドの説明を書き、「これは、名前フィールドです」
年齢intは「これは年齢フィールドです」
}
JSONのパッケージ
json.Marshal()
注意:
JSONパッケージ化、
フィールド1資本は、彼らができる前に、構造体に配置する必要があります
以下は、2つの方法で開始した声明詰めプログラムであり、
メインパッケージ のインポート( "エンコーディング/ jsonの" "FMT" ) タイプの学生のstruct { 名の文字列を`JSON: "Student_name"` 年齢はint `JSON: "student_age"` スコアはint `JSON:score` } メインFUNC(){ //声明 のvar STU学生=学生{ 名: "stu01"、 年齢:10、 スコア:100、 } データ、ERR:= json.Marshal(STU)//打包、返回值为バイト の場合、ERR = nilの{! fmt.Println ( "JSONエンコードSTU faild、ERR"、ERR) リターン } fmt.Println(文字列(データ))//把バイト转化成列 } // { "Student_name": "stu01"} 次のように書くことができます。 メインパッケージ のインポート( "エンコーディング/ jsonの" "FMT" ) タイプの学生のstruct { 名の文字列を`JSON: "Student_name"` 年齢はint `JSON: "student_age"` スコアはint `JSON:score` } メインFUNC(){ //初始化 VAR STU *学生=新(学生) stu.Name = "stu01" データは、ERR:= json.Marshal(STU)//打包、返回值为バイト ERR = nilの{もし! fmt.Println(「JSONエンコードSTU faild、ERR」、ERR) リターン } fmt.Println(文字列(データ))//把バイト转化成列 } // { "Student_name": "stu01"}
あるいは、例えば、
メインパッケージ のインポート( "符号化/ JSON" "FMTを" ) 学生構造体を入力し、{ 名前列`JSON: "Student_name"` 年齢INT `JSON: "student_age"` スコアINT `JSON:score` } メインFUNC(){ //初始化 のvar STU *学生=新(学生) stu.Name = "stu01" stu.Age = 20 stu.score = 90の データ、ERR:= json.Marshal(STU)//打包、返回值为バイト 誤る場合=!ゼロ{ fmt.Println( "JSONエンコードSTU faild、ERR"、ERR) リターン } fmt.Println(文字列(データ))//把バイト转化成列 } // { "Student_name": "stu01"、 "student_age" :20}
匿名フィールド
構造体のフィールドは、匿名フィールドと呼ばれる、名前を付けることはできません
型車の構造体{
名前の文字列
年齢はint
}
タイプ列車のstruct {
カー//匿名フィールド
スタートtime.Time //有名なフィールド
int型//匿名フィールド
}
匿名フィールドには、どのようにそれにアクセスするには?
メインパッケージ のインポート( "FMT" "時間" ) タイプstruct {カート 名文字列 年齢はint } タイプstruct {列車の カート int型 STRTのtime.time } FUNCメイン(){ VARの列車T //通常の書き込み t.Cart.name = " 001 " t.Cart.age = 11 //次の文言と略記することができ、正式な表記上記 t.name =" 001 " t.age = 11 t.int = 200である fmt.Println(T) }
匿名紛争管理フィールド
種類カートのstruct { 名前の文字列の 年齢はint } 型列車のstruct { カート STRT time.Time 年齢はint }
上記の匿名の紛争については、優先順位の原則があります:
二つの構造がある場合、略語は、見つけるために、同じフィールド、優先フィールド自体を持っています
構造体を入力{ INT } 型B構造体{ int型 のB INT } C型構造体{ A 、B }
上記の匿名の紛争については、手動でフィールド缶を指定する必要があり、またはエラーになります
2.メンバ変数
- アクセス制御機構
構造体のメンバ変数名を大文字にすると、この変数は(すなわち、他のパッケージがアクセスできる)が導かれます。
メンバ変数を含むことができる構造が誘導され、同時に非誘導することができます
{構造体型 時間// INT抽出 分INTが導出されない// }
- 制限事項
命名構造Sの種類、すなわち重合のタイプは、それ自身を含むことができない、同じ構造型Sのメンバ変数を定義していません。ただし、Sは、ポインタタイプS、すなわち、* Sを定義することができ 次のとおりです。
構造体{S型 値int // S //エラー次に 次に* S //正しいです }
構造の比較3。
- すべてのメンバ変数の構造を比較することができた場合は、構造を比較することができます。二つの構造の比較は、使用または==!=することができます。
メインパッケージ インポート"FMT"を メイン(){funcを タイプCの構造体{ INT B列 } = C {A:1、B: "ABC"} C1 、C2 = C {A 1、B: "ABC"} C3:= C {A 2、B: "ABC"} fmt.Println(c1.A == c2.A && c1.B == c2.B)//真 fmt.Println(C == C2)/ /真与上等价 fmt.Println(c1.A == c3.A && c1.B == c3.B)//偽 fmt.Println(C == C3)//偽与上等价 }
- そして、マップの同等のタイプの構造のような比較の他のタイプは、キータイプとして使用することができます。
メインパッケージ インポート"FMT" メインFUNC(){ C型構造体{ int型 B列 } =メイク(地図[C] INT):融点 キー:= C {A 1、B: "ABC"} MP [キー] = 9 fmt.Println(MP [C {A 1、B: "ABC"}])// 9 fmt.Println(MP)//マップ[{1つの} ABC:9] }
4.匿名とネスティング構造体のメンバ
- 匿名のメンバーとして知られるこの構造体のメンバー、私たちは名前なしで定義するボディ構造のメンバーを可能にするために行く、あなただけのタイプを指定する必要があります。構造体メンバのこのタイプは、名前のポインタ型のポインティングの名前やタイプでなければなりません。この構造ネストされた関数の、我々は中間変数の長いリストを指定するのではなく、必要な変数に直接アクセスすることができるからです。
パッケージメイン
輸入「FMT」
タイプポイントのstruct {
Xはint
Y int型
}
型サークル構造体{
ポイント
}
タイプホイール構造体{
*ポイント
}
FUNCのmain(){
サークルC VAR
= 10 c.Point.Xと同等CX = 10 //
= 10 c.Point.Yに相当CY = 10 //
fmt.Println(C)
ホイールのw
P:=ポイント{1、3}
w.Point =&P
fmt.Println(w.Point.X)
}
- 構造はリテラルショートカットを初期化していない、あなたは型定義の形状に従わなければなりません。
"FMT"インポート タイプポイントのstruct { X INT Yはint } 入力サークル構造体{ ポイント } メインFUNC(){ VAR Cサークル // C =サークル{1,1} //错误 C =サークル{ポイント{1,1} } //正确 C =サークル{ポイント:ポイント{1,1}} //正确 fmt.Println(C) }
-
「匿名のメンバーが」暗黙の名前を持っているので、あなたは、その構造中に同じタイプの2人の匿名のメンバーを定義することはできませんそれ以外の場合には、紛争につながります。名前匿名のメンバーが自分のタイプによって決定されると、そのエクスポート可能もそのタイプによって決定されます。次の例では、これらの2人の匿名のポイントやサークルのメンバーは、二つの構造が(ポイントおよび円)が導出されていない場合でも、導出されます。
主パッケージ のインポート"FMT" タイプstruct点{ X-INT Y INT } タイプstruct {サークル ポイント } ホイール構造体{入力 サークル } FUNCメイン(){ VAR Wホイール WX = //を8はw.circle.point.Xと同等です= 8、WXが導出され、w.circle.point.Xが導出されていない fmt.Println(W) }
構造の方法
- 定義
方法の正常な機能のような文と宣言し、関数名の前の知識は追加のパラメータを追加しました。このメソッドのパラメータは、このパラメータに対応するタイプに結合します。
パラメータpの付加的な方法となる受信者呼び出し側オブジェクトにメッセージを送信する方法を説明するために、以前のオブジェクト指向言語に由来します。
メインパッケージ "FMT"インポート タイプポイントのstruct { X INT Yはint } FUNC(P点)プリント(){ fmt.Println(pXの、はpY) } メインFUNC(){ =ポイント{1、2} W VAR w.printを() }
- 移動して、他の多くのオブジェクト指向言語、ポインタ型とのインターフェイスタイプのいずれかの種類以外の方法に結合することができる。この方法は限界を定義しました。追加の動作を定義する単純型(プラスチック製、文字列、スライス、マップ、あるいは機能、など)のために非常に便利です。
パッケージメイン インポート"FMT" //整形 III型のint FUNC(III I)プリント(){ fmt.Println(I) } //函数 FUNCテスト(){ fmt.Println( "試験") } 型FunTのFUNC() (FunT F)FUNCプリント(){ fmt.Println(F) } メインFUNC(){ FunT F VAR F =試験 F.PRINT() VAR I III = 3 i.print() }
- メソッドポインタの受信者:原因関数呼び出しには、各変数の引数をコピーしますか引数が大きすぎると、我々は引数全体をコピーしないようにしたい場合は、私たちは、変数のアドレスを渡すためにポインタを使用する必要があります。これはまた、我々はポインタ型にバインドし、受信者の更新に適用されます。あなたがメソッドを呼び出し、コンパイラは変数の暗黙的な変換。 構造のメソッドが正常に呼び出すことができる条件を要約すると:
- 引数の受信者と受信者は、としてであるか、またはT * T.であるように同じパラメータ型であります (5,7)
- T受信機は、引数の型である変数、パラメータTは、受信機タイプ、コンパイラよい暗黙アドレス取得変数(3)です*。
- 引数が受信者であるTパラメータTタイプは、受信型で、コンパイラが暗黙的に実際の値を取得します。T型に対してコンパイラ:理由の(2,6)の一つは、8コンパイルエラーということである彼らは一時変数の地面を得ることができないので、タイプTの暗黙の変換、受信者のみ引数は、成功するためには、可変です
主パッケージ のインポート"FMT" タイプstruct点{ X-INT YのINT } FUNC(点P)を印刷(){ (pXの、はpYとの)fmt.Println } FUNC(P *ポイント)SCALEBY(INT因子){ PXの=因子* はpY& =因子* } FUNCメイン(){ 。P:=ポイント1 {、} 1 PTR:P =& 。。p.Print(1)// 正しい 。ptr.Print()// 2正しく p.ScaleBy(2)// 3.正しい ptr.ScaleBy(2)// 4.適切 ポイント{1,1}の.print( )// 5. 正しい (&ポイント{1,1} )。(印刷)// 6. 正しい (&ポイント{1 、1})。SCALEBY(2 )// 7 正しく //ポイント{1,1} .ScaleBy (2)// 8. エラー }
- nilは、正当な受信者である:いくつかの関数は、引数としてNULLポインタを可能にするように、方法は、受信者のポインタがゼロであることができ
メインパッケージ "FMT"インポート のstruct {入力 データINT } FunPtrA(){FUNC(* A)を fmt.Println( "FunPtrA") } メインFUNC(){ VAR PTRA * A PTRA =ゼロ ptrA.FunPtrA()/ / FunPtrA }
- 埋め込み型で構成構造: メインの議論ここに埋め込まれた構造と構造体へのポインタ、構造関数のソース定義へのアクセス権。