はじめに
おはようございます。こんにちは。こんばんは。
Watatakuです。
本日の内容は「Goのポインタ、構造体について改めて勉強しました。」と言う内容でやっていきます。
自分と同じくポインタの概念が存在しない言語から始めた人にとっては、なかなかとっつきにくいものだと思います。
なのでこの機会に一緒に理解を深めていきましょう。
「Go言語を真剣に勉強してみた〜基本構文編①(変数、定数、条件分岐、繰り返し処理)〜」についてはこちらから。
「Go言語を真剣に勉強してみた〜基本構文編②(配列)〜」についてはこちらから。
「Go言語を真剣に勉強してみた〜基本構文編③(関数)〜」についてはこちらから。
ポインタ
そもそもポインタとはなんぞやと言う話からします。
ポインタとは、メモリのアドレス情報のことです。
変数のアドレス取得方法
Goでは&
を用いることで変数のアドレスの取得が可能です。
例えば &hogeで変数hogeのアドレスを取得することが可能
です。
ポインタ型変数
ポインタ型で宣言された変数のことです。
つまり、メモリ上のアドレスを値として入れられる変数のことです。
ポインタ型にしたい変数に *
をつけて宣言します。
func main() {
var hoge int = 10//int型の変数
var bow *int = &hoge //int型へのポイント型
fmt.Println(hoge) //=> 10
fmt.Println(bow) //=> 0x10414020
}
※初期値が指定されていない場合、Go 言語のポインタは nil (nil ポインタ) に初期化されます
ポインタ型変数の中身へのアクセス方法
ポインタ型変数名の前に *
をつけることで変数の中身へのアクセスが可能です。
例えば *bow とすることで bow の値の参照が可能
です。
func main() {
var hoge int = 10
var bow *int = &hoge
fmt.Println(*bow) //=> 10
}
構造体
Goにはオブジェクト指向言語におけるclassというものは存在しません。
似た役割として関連する情報をひとまとめにする構造体が使用されます。
構造体の定義
type 構造体名 struct {
フィールド名 データ型
}
※Goの場合、大文字から始まる名前は、他のパッケージからアクセス可能となります。
一方、小文字で始まる名前の場合、他のパッケージからアクセス不可能です(カプセル化)。同じパッケージ内であれば小文字でもアクセス可能です。
構造体の初期化
構造体の初期化方法は複数あります.
- ①変数定義後にフィールドを設定する方法
- ②{} で順番にフィールドの値を渡す方法
- ③フィールド名を
:
で指定する方法 - ④初期化関数を作成することで初期化をする
①変数定義後にフィールドを設定する方法
type Person struct {
firstName string
age int
}
func main(){
var mike Person
mike.firstName = "Mike"
mike.age = 20
fmt.Println(mike.firstName, mike.age) //=> Mike 20
}
②{} で順番にフィールドの値を渡す方法
type Person struct {
firstName string
age int
}
func main(){
bob := Person{"Bob", 30}
fmt.Println(bob.firstName, bob.age) //=>Bob 30
}
③フィールド名を : で指定する方法
type Person struct {
firstName string
age int
}
func main(){
sam := Person{age: 15, firstName: "Sam"}
fmt.Println(sam.firstName, sam.age) //=>Sam 15
}
④初期化関数を作成することで初期化をする
type Person struct {
firstName string
age int
}
func newPerson(firstName string, age int) *Person{
person := new(Person)
person.firstName = firstName
person.age = age
return person
}
func main(){
var jen *Person = newPerson("Jennifer", 40)
fmt.Println(jen.firstName, jen.age) //=>Jennifer 40
}
メソッド
Goの構造体にはもう1つ便利な機能があります。それがメソッドです。
下記構文でメソッドを定義することができます。
func (レシーバ名 レシーバの型) 関数名(引数) (戻り値) {
//処理
}
では上記で作った、User構造体にメソッドを定義して使ってみましょう。
func (u User) greet() string {
return "hello," + u.Name;
}
var user *User = newUser("taro", 30, "hoge@example.ac.jp")
user.greet()
greetメソッドではレシーバーにUserを指定しています。メソッドはフィールドと同じように、「.」 を使ってアクセスします。
メソッドではレシーバ(User)のもつフィールドにアクセスすることが可能です。
また、同じ名前のメソッドがあっても、レシーバが異なればメソッドは別のものとして扱われるので注意してください。
以上。
もし何か間違っている等のご指摘があればご連絡ください。
長くなりましたが、最後まで読んで頂きありがとうございました。
次回は「Go言語を真剣に勉強してみた〜パッケージ編〜」です。
よろしければ、Go言語を真剣に勉強してみた〜環境構築編〜もご覧ください。