[ja] apply patch

This commit is contained in:
Shin Kojima
2013-12-26 00:07:32 +09:00
parent 4a31adff6d
commit 890e454486

View File

@@ -1,211 +1,214 @@
# 2.4 struct型 # 2.4 struct型
## struct ## struct
Go言語では、Cや他の言語と同じように、他の型の属性やフィールドのコンテナとして新しい型を宣言することができます。例えば、一個人のエンティティを表している`person`型を作成することができます。このエンティティは属性を持っています:性別と年齢です。このような型は`struct`と呼ばれます。以下にコードを示します: Go言語では、Cや他の言語と同じように、他の型の属性やフィールドのコンテナとして新しい型を宣言することができます。例えば、一個人のエンティティを表している`person`型を作成することができます。このエンティティは属性を持っています:性別と年齢です。このような型は`struct`と呼ばれます。以下にコードを示します:
type person struct { type person struct {
name string name string
age int age int
} }
お分かりいただけましたでしょうかstructの宣言はこのように簡単です。上の型はつのフィールドを持っています。 お分かりいただけましたでしょうかstructの宣言はこのように簡単です。上の型はつのフィールドを持っています。
- string型のフィールドnameはユーザの名前を保存するプロパティです。 - string型のフィールドnameはユーザの名前を保存するプロパティです。
- int型のフィールドageはユーザの年齢を保存するプロパティです。 - int型のフィールドageはユーザの年齢を保存するプロパティです。
どのようにstructは使用されるのでしょうか下のコードをご覧ください。 どのようにstructは使用されるのでしょうか下のコードをご覧ください。
type person struct { type person struct {
name string name string
age int age int
} }
var P person // Pは現在person型の変数です。 var P person // Pは現在person型の変数です。
P.name = "Astaxie" // "Astaxie"を変数Pのnameプロパティに代入します。 P.name = "Astaxie" // "Astaxie"を変数Pのnameプロパティに代入します。
P.age = 25 // "25"を変数Pのageプロパティに代入します。 P.age = 25 // "25"を変数Pのageプロパティに代入します。
fmt.Printf("The person's name is %s", P.name) // Pのnameプロパティにアクセスします。 fmt.Printf("The person's name is %s", P.name) // Pのnameプロパティにアクセスします。
上のようなPの宣言以外に他にも二種類の宣言方法があります。 上のようなPの宣言以外に他にもいくつかの宣言方法があります。
- 1.順序にしたがって初期化する。 - 1.順序にしたがって初期化する。
P := person{"Tom", 25} P := person{"Tom", 25}
- 2.`field:value`の方法によって初期化します。この場合は順序は任意でかまいません。 - 2.`field:value`の方法によって初期化します。この場合は順序は任意でかまいません。
P := person{age:24, name:"Tom"} P := person{age:24, name:"Tom"}
以下ではひと通りのstructの使用例をご説明します。 - 3.もちろん`new`関数を通してポインタを作ることもできます。このPの型は*personです。
package main P := new(person)
import "fmt"
以下ではひと通りのstructの使用例をご説明します。
// 新しい型を宣言します。
type person struct { package main
name string import "fmt"
age int
} // 新しい型を宣言します。
type person struct {
// 二人の年齢を比較します。年齢が大きい方の人を返し、また年齢差も返します。 name string
// structも値渡しです。 age int
func Older(p1, p2 person) (person, int) { }
if p1.age>p2.age { // p1とp2の二人の年齢を比較します。
return p1, p1.age-p2.age // 二人の年齢を比較します。年齢が大きい方の人を返し、また年齢差も返します。
} // structも値渡しです。
return p2, p2.age-p1.age func Older(p1, p2 person) (person, int) {
} if p1.age>p2.age { // p1とp2の二人の年齢を比較します。
return p1, p1.age-p2.age
func main() { }
var tom person return p2, p2.age-p1.age
}
// 初期値を代入します。
tom.name, tom.age = "Tom", 18 func main() {
var tom person
// 2つのフィールドを明確に初期化します。
bob := person{age:25, name:"Bob"} // 初期値を代入します。
tom.name, tom.age = "Tom", 18
// structの定義の順番に従って初期化します。
paul := person{"Paul", 43} // 2つのフィールドを明確に初期化します。
bob := person{age:25, name:"Bob"}
tb_Older, tb_diff := Older(tom, bob)
tp_Older, tp_diff := Older(tom, paul) // structの定義の順番に従って初期化します。
bp_Older, bp_diff := Older(bob, paul) paul := person{"Paul", 43}
fmt.Printf("Of %s and %s, %s is older by %d years\n", tb_Older, tb_diff := Older(tom, bob)
tom.name, bob.name, tb_Older.name, tb_diff) tp_Older, tp_diff := Older(tom, paul)
bp_Older, bp_diff := Older(bob, paul)
fmt.Printf("Of %s and %s, %s is older by %d years\n",
tom.name, paul.name, tp_Older.name, tp_diff) fmt.Printf("Of %s and %s, %s is older by %d years\n",
tom.name, bob.name, tb_Older.name, tb_diff)
fmt.Printf("Of %s and %s, %s is older by %d years\n",
bob.name, paul.name, bp_Older.name, bp_diff) fmt.Printf("Of %s and %s, %s is older by %d years\n",
} tom.name, paul.name, tp_Older.name, tp_diff)
### structの匿名フィールド fmt.Printf("Of %s and %s, %s is older by %d years\n",
上でstructをどのように定義するかご紹介しました。定義する際はフィールド名とその型が一つ一つ対応しています。実はGoは型だけの定義もサポートしています。これはフィールド名を書かない方法ではなく、匿名フィールドです。組み込みフィールドとも呼ばれます。 bob.name, paul.name, bp_Older.name, bp_diff)
}
匿名フィールドがstructである場合、このstructがもつすべてのフィールドは隠されたまま現在定義しているこのstructに導入されます。
### structの匿名フィールド
ひとつ例をお見せしましょう。上の説明がより具体的になります。 上でstructをどのように定義するかご紹介しました。定義する際はフィールド名とその型が一つ一つ対応しています。実はGoは型だけの定義もサポートしています。これはフィールド名を書かない方法ではなく、匿名フィールドです。組み込みフィールドとも呼ばれます。
package main 匿名フィールドがstructである場合、このstructがもつすべてのフィールドは隠されたまま現在定義しているこのstructに導入されます。
import "fmt"
ひとつ例をお見せしましょう。上の説明がより具体的になります。
type Human struct {
name string package main
age int import "fmt"
weight int
} type Human struct {
name string
type Student struct { age int
Human // 匿名フィールド、デフォルトでStudentはHumanのすべてのフィールドを含むことになります。 weight int
speciality string }
}
type Student struct {
func main() { Human // 匿名フィールド、デフォルトでStudentはHumanのすべてのフィールドを含むことになります。
// 学生を一人初期化します。 speciality string
mark := Student{Human{"Mark", 25, 120}, "Computer Science"} }
// 対応するフィールドにアクセスします。 func main() {
fmt.Println("His name is ", mark.name) // 学生を一人初期化します。
fmt.Println("His age is ", mark.age) mark := Student{Human{"Mark", 25, 120}, "Computer Science"}
fmt.Println("His weight is ", mark.weight)
fmt.Println("His speciality is ", mark.speciality) // 対応するフィールドにアクセスします。
// 対応するメモ情報を修正します。 fmt.Println("His name is ", mark.name)
mark.speciality = "AI" fmt.Println("His age is ", mark.age)
fmt.Println("Mark changed his speciality") fmt.Println("His weight is ", mark.weight)
fmt.Println("His speciality is ", mark.speciality) fmt.Println("His speciality is ", mark.speciality)
// 彼の年齢情報を修正します。 // 対応するメモ情報を修正します。
fmt.Println("Mark become old") mark.speciality = "AI"
mark.age = 46 fmt.Println("Mark changed his speciality")
fmt.Println("His age is", mark.age) fmt.Println("His speciality is ", mark.speciality)
// 体重情報修正します。 // 彼の年齢情報修正します。
fmt.Println("Mark is not an athlet anymore") fmt.Println("Mark become old")
mark.weight += 60 mark.age = 46
fmt.Println("His weight is", mark.weight) fmt.Println("His age is", mark.age)
} // 体重情報も修正します。
fmt.Println("Mark is not an athlet anymore")
図解: mark.weight += 60
fmt.Println("His weight is", mark.weight)
![](images/2.4.student_struct.png?raw=true) }
2.7 StudentとHumanの継承方法 解:
我们看到Student访问属性age和name的时候就像访问自己所有用的字段一样匿名字段就是这样能够实现字段的继承。是不是很酷啊还有比这个更酷的呢那就是student还能访问Human这个字段作为字段名。请看下面的代码是不是更酷了。 ![](images/2.4.student_struct.png?raw=true)
Studentがageとnameの属性にアクセスする際、あたかも自分のフィールドであるかのようにアクセスしたのをご覧いただけるかと思います。そうです。匿名フィールドというのはこういうものです。フィールドの継承を実現できるのです。これってクールじゃないですかもっとクールにする方法もありますよ。studentはHumanのフィールド名でアクセスできます。下のコードを御覧ください。ほら、とってもクールでしょ
図2.7 StudentとHumanの継承方法
mark.Human = Human{"Marcus", 55, 220}
mark.Human.age -= 1 我们看到Student访问属性age和name的时候就像访问自己所有用的字段一样匿名字段就是这样能够实现字段的继承。是不是很酷啊还有比这个更酷的呢那就是student还能访问Human这个字段作为字段名。请看下面的代码是不是更酷了。
Studentがageとnameの属性にアクセスする際、あたかも自分のフィールドであるかのようにアクセスしたのをご覧いただけるかと思います。そうです。匿名フィールドというのはこういうものです。フィールドの継承を実現できるのです。これってクールじゃないですかもっとクールにする方法もありますよ。studentはHumanのフィールド名でアクセスできます。下のコードを御覧ください。ほら、とってもクールでしょ
匿名によるアクセスとフィールドの修正はとても便利です。でも単なるstructのフィールドですから、すべてのビルトイン型と自分で定義した型をすべて匿名フィールドとみなすことができます。下の例をご覧ください。
mark.Human = Human{"Marcus", 55, 220}
package main mark.Human.age -= 1
import "fmt"
匿名によるアクセスとフィールドの修正はとても便利です。でも単なるstructのフィールドですから、すべてのビルトイン型と自分で定義した型をすべて匿名フィールドとみなすことができます。下の例をご覧ください。
type Skills []string
package main
type Human struct { import "fmt"
name string
age int type Skills []string
weight int
} type Human struct {
name string
type Student struct { age int
Human // 匿名フィールド、struct weight int
Skills // 匿名フィールド、自分で定義した型。string slice }
int // ビルトイン型を匿名フィールドとします。
speciality string type Student struct {
} Human // 匿名フィールド、struct
Skills // 匿名フィールド、自分で定義した型。string slice
func main() { int // ビルトイン型を匿名フィールドとします。
// 学生Jannを初期化します。 speciality string
jane := Student{Human:Human{"Jane", 35, 100}, speciality:"Biology"} }
// ここで対応するフィールドにアクセスしてみます。
fmt.Println("Her name is ", jane.name) func main() {
fmt.Println("Her age is ", jane.age) // 学生Jannを初期化します。
fmt.Println("Her weight is ", jane.weight) jane := Student{Human:Human{"Jane", 35, 100}, speciality:"Biology"}
fmt.Println("Her speciality is ", jane.speciality) // ここで対応するフィールドにアクセスしてみます。
// 彼のskill技能フィールドを修正します。 fmt.Println("Her name is ", jane.name)
jane.Skills = []string{"anatomy"} fmt.Println("Her age is ", jane.age)
fmt.Println("Her skills are ", jane.Skills) fmt.Println("Her weight is ", jane.weight)
fmt.Println("She acquired two new ones ") fmt.Println("Her speciality is ", jane.speciality)
jane.Skills = append(jane.Skills, "physics", "golang") // 彼のskill技能フィールドを修正します。
fmt.Println("Her skills now are ", jane.Skills) jane.Skills = []string{"anatomy"}
// 匿名ビルトイン型のフィールドを修正します。 fmt.Println("Her skills are ", jane.Skills)
jane.int = 3 fmt.Println("She acquired two new ones ")
fmt.Println("Her preferred number is", jane.int) jane.Skills = append(jane.Skills, "physics", "golang")
} fmt.Println("Her skills now are ", jane.Skills)
// 匿名ビルトイン型のフィールドを修正します。
上の例のとおり、structはstructを匿名フィールドとするだけでなく、自分で定義した型やビルトイン型も匿名フィールドとすることができます。また、対応するフィールド上で関数操作を行うこともできます例えば例の中のappendです jane.int = 3
fmt.Println("Her preferred number is", jane.int)
ここで一つ疑問がでてきますもしhumanにphoneというフィールドがあったとすると、studentもphoneと呼ばれるフィールドができます。これはどうすべきでしょうか }
Goでは簡単にこの問題を解決することができます。外側が優先的にアクセスされますので、`student.phone`とアクセスした場合studentの中のフィールドにアクセスし、humanのフィールドにはアクセスしません 上の例のとおり、structはstructを匿名フィールドとするだけでなく、自分で定義した型やビルトイン型も匿名フィールドとすることができます。また、対応するフィールド上で関数操作を行うこともできます例えば例の中のappendです
のように匿名フィールドを通じてフィールドを継承することができます。当然もしあなたが対応する匿名型のフィールドにアクセスしたくなったら、匿名フィールドの名前からアクセスすることができます。下の例をご覧ください。 こで一つ疑問ができますもしhumanにphoneというフィールドがあったとすると、studentもphoneと呼ばれるフィールドができます。これはどうすべきでしょうか
package main Goでは簡単にこの問題を解決することができます。外側が優先的にアクセスされますので、`student.phone`とアクセスした場合studentの中のフィールドにアクセスし、humanのフィールドにはアクセスしません。
import "fmt"
このように匿名フィールドを通じてフィールドを継承することができます。当然もしあなたが対応する匿名型のフィールドにアクセスしたくなったら、匿名フィールドの名前からアクセスすることができます。下の例をご覧ください。
type Human struct {
name string package main
age int import "fmt"
phone string // Human型がもつフィールド
} type Human struct {
name string
type Employee struct { age int
Human // 匿名フィールドHuman phone string // Human型がもつフィールド
speciality string }
phone string // 社員のphoneフィールド
} type Employee struct {
Human // 匿名フィールドHuman
func main() { speciality string
Bob := Employee{Human{"Bob", 34, "777-444-XXXX"}, "Designer", "333-222"} phone string // 社員のphoneフィールド
fmt.Println("Bob's work phone is:", Bob.phone) }
// もし我々がHumanのphoneフィールドにアクセスする場合は
fmt.Println("Bob's personal phone is:", Bob.Human.phone) func main() {
} Bob := Employee{Human{"Bob", 34, "777-444-XXXX"}, "Designer", "333-222"}
fmt.Println("Bob's work phone is:", Bob.phone)
// もし我々がHumanのphoneフィールドにアクセスする場合は
## links fmt.Println("Bob's personal phone is:", Bob.Human.phone)
* [目次](<preface.md>) }
* 前へ: [フローと関数](<02.3.md>)
* 次へ: [オブジェクト指向](<02.5.md>)
## links
* [目次](<preface.md>)
* 前へ: [フローと関数](<02.3.md>)
* 次へ: [オブジェクト指向](<02.5.md>)