2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Go言語を真剣に勉強してみた〜基本構文編④(ポインタ、構造体)〜

Last updated at Posted at 2018-09-24

はじめに

おはようございます。こんにちは。こんばんは。
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言語を真剣に勉強してみた〜環境構築編〜もご覧ください。

2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?