0
0

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 1 year has passed since last update.

Go 基本文法【ポインタ・構造体・配列編】

0
Last updated at Posted at 2023-06-21

はじめに

今回はGoの基本文法である「ポインタ・構造体・配列」についてです。

目次

  1. Pointers : ポインタ
  2. Structs : 構造体
  3. Embedded Structs : 構造体の埋め込み(継承)
  4. Arrays : 配列
  5. 参考文献

Pointers : ポインタ

ポインタとは、値のメモリアドレスのことです。
変数の型の前に*が付くものはポインタ型変数、付かないものは変数となります。

var 変数名 *

変数には格納されている値とは別にアドレス情報を持っています。いわば変数の住所ですね。
Goでは&を使って、変数のアドレスを取得することができます。

main.go
package main

import "fmt"

func main() {
	// string 型の変数 str
	var str string = "ポインタのテスト"
	
	// string 型へのポインタ型 str_pointer 変数に str のアドレスを格納
	var str_pointer *string = &str

	fmt.Println(str) // => ポインタのテスト
	fmt.Println(str_pointer) // => 0x000096210
}

ポインタ型変数名の前に*をつければ、変数の値を取得することができます。
*をつければアドレス、つけなければ値へのアクセスとなります。

main.go
fmt.Println(*str_pointer) // => ポインタのテスト

主な用途は、引数やレシーバを経由する関数内で書き換えたい時です。
Goでは、書き換え対象はポインタとして渡す必要があります。

main.go
package main

import "fmt"

type Pointer struct{ value int }

// ポインタ型でないため、+5されない(書き換え不可)
func (h Pointer) Not_Pointer(v int) {
	h.value = v + 5
}

// ポインタ型のため、+5される(書き換え可)
func (h *Pointer) Pointer(v int) {
	h.value = v + 5
}

func main() {
	var h Pointer // データ書き換え対象の変数

	h.Not_Pointer(0)
	fmt.Printf("Not_Pointer:%v\n", h.value) // => Not_Pointer:0

	h.Pointer(0)
	fmt.Printf("Pointer:%v\n", h.value) // => Pointer:5
}

Structs : 構造体

Goにクラスは存在しません。
構造体はクラスと似た役割を果たし、関連情報をひとまとめにすることができます。

構造体は、typestructを使って定義(個別・複数どちらでも定義可)します。
構造体はフィールドの集まりです。

type 構造体名 struct {
    フィールド名 
    フィールド名 
}

フィールドへは.を使ってアクセスします。

構造体のポインタ名.構造体のフィールド名 = 1

構造体の初期化方法は複数あります。
 ①変数定義後にフィールドを設定する方法
 ②{}内で順番にフィールドの値を渡す方法
 ③フィールド名をで指定する方法

// ①
type People struct {
   name string 
   age int
}

func main(){
  var jack People
  jack.name = "Jack"
  jack.age = 20
  fmt.Println(jack.name, jack.age) // => Jack 20
}
// ②
func main(){
  jack := People{"Jack", 20}
  fmt.Println(jack.name, jack.age) // => Jack 20
}
// ③
func main(){
  jack := People{age: 20, name: "Jack"}
  fmt.Println(jack.name, jack.age) // => Jack 20
}

以下のように、初期化関数を作成し初期化することも一般的のようです。

func newPerson(name string, age int) *People{
     person := new(People) // 初期化する
	 person.name = name // name フィールドへ値を代入
	 person.age = age // age フィールドへ値を代入
	 return person
}

func main(){
  var jack *People = newPerson("Jack", 20)
  fmt.Println(jack.name, jack.age) // => Jack 20
}

Goにはクラスの概念がないですが、構造体内でメソッドを定義することができます。
メソッドの定義方法は以下の通りです。関数と異なる点はレシーバ引数の部分だけです。

func (レシーバ引数) 関数名(引数) 戻り値の型 {
    関数の本体
}
main.go
package main

import "fmt"

type People struct {
   name string 
   age int
}

// メソッド定義 : Poeple という構造体に対して introduction というメソッドを定義
// introduction メソッドは p という名前の People 型のレシーバを持つ
func (p People) introduction(greetings string) string{
    return greetings + " I am " + p.name
}

func main(){
  jack := People{"Jack", 20}
  fmt.Println(jack.introduction("Hello")) // => Hello I am Jack
}

Embedded Structs : 構造体の埋め込み(継承)

他の言語にあるクラス継承に似た機能として構造体の埋め込みがあります。
1つの構造体を別の構造体へ埋め込むことが可能です。

main.go
package main

import "fmt"

// 構造体宣言
type character struct {
	name string
	age  int
}

func main() {
	// 構造体へデータセット
	c := character{
		name: "Jack",
		age:  20,
	}
	
	// 構造体自体を出力
	fmt.Println(c) // => {Jack 20}
	
	// 構造体のフィールドデータを出力
	fmt.Println(c.name, c.age) // => Jack 20
}

Arrays : 配列

配列は、同じ型を持つ値(要素)を並べたものです。
Goにおける配列は固定長配列のため、最初に宣言した配列サイズは変更できません。

配列の宣言方法は以下の通りです。
 ① var 変数名 [長さ]型
 ② var 変数名 [長さ]型 = [大きさ]型{初期値1, 初期値n}
 ③ 変数名 := [...]型{初期値1, 初期値n}

// ①
func main(){
   var arr[2] string 
       arr[0] = "Hello World"
       arr[1] = "Go"
       fmt.Println(arr[0], arr[1]) //=> Hello World
       fmt.Println(arr) //=> [Hello World]
}
// ②
func main(){
   var arr[2] string = [2]string {"Hello", "Go"}
       fmt.Println(arr[0], arr[1]) //=> Hello Go
       fmt.Println(arr) //=> [Hello Go]
}
// ③
// 要素数は省略可、要素数は自動カウントしている
func main(){
     arr := [...] string{"Hello", "Go"}
     fmt.Println(arr[0], arr[1]) //=> Hello Go}
     fmt.Println(arr) //=> [Hello Go]
}

参考文献

A Tour of Go
Goで学ぶポインタとアドレス
Go言語(golang) 構造体の定義と使い方
[Go]構造体を学ぶ
Go 言語の配列

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?