👌

【Go備忘録】静的型付け・型推論・関数・構造体・レシーバ・Go Modules・Packages・Imports

2024/04/17に公開

静的型付け・型推論あり

:= 演算子

関数の中では、 var 宣言の代わりに、短い := の代入文を使い、暗黙的な型宣言ができる。

関数の外では、キーワードではじまる宣言( varfunc, など)が必要で、 := での暗黙的な宣言は利用できない。

型推論

明示的な型を指定せずに変数を宣言する場合( := や var = のいずれか)、変数の型は右側の変数から型推論される。

i := 42           // int
f := 3.142        // float64
g := 0.867 + 0.5i // complex128

セロ値

変数に初期値を与えずに宣言すると、ゼロ値( zero value )が与えられる。

package main

import "fmt"

func main() {
	var i int     // 0
	var f float64 // 0
	var b bool   // false
	var s string  // 空文字列
	fmt.Printf("%v %v %v %q\n", i, f, b, s) // 0 0 false ""
}

型変換

C言語とは異なり、Goでの型変換は明示的な変換が必要。

変数 v 、型 T があった場合、 T(v) は、変数 v を T 型へ変換する。

i := 42
f := float64(i)
u := uint(f)

定数

定数( constant )は、 const キーワードを使って変数と同じように宣言する。

定数は、文字(character)、文字列(string)、boolean、数値(numeric)のみで使える。

定数は := を使って宣言できない。

%v :フォーマット指定子

Go言語では fmt.Sprintf 関数(および関連する fmt パッケージの関数)でフォーマット指定子 %v を使用する。Go言語の fmt パッケージは、"formatted I/O" または "formatted input/output" の略。

%v フォーマット指定子は非常に汎用的で、プリミティブなデータタイプ(整数、浮動小数点数、ブール値、文字列など)から、複雑なデータ構造(配列、スライス、マップ、構造体など)まで、様々なタイプの値をデフォルトの形式で出力するのに使用される。

  • fmt.Sprintf はフォーマットされた文字列を返し、それを変数に保存したり、他の関数への入力として使用することができる。
  • fmt.Printf はフォーマットされた文字列を直接標準出力(通常はコンソール)に書き出す。
package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func main() {
    person := Person{Name: "Alice", Age: 30}
    fmt.Printf("Person details: %v\n", person)  // 出力:Person details: {Alice 30}

    scores := []int{92, 85, 88} // int型の配列を宣言
    fmt.Printf("Scores: %v\n", scores)  // 出力:Scores: [92 85 88]

    greeting := fmt.Sprintf("Hi, %v. Welcome!", person.Name)
    fmt.Println(greeting)  // 出力:"Hi, Alice. Welcome!"
}

関数

関数はfuncキーワードで始まり、引数と戻り値の型が必要(静的型付け)

変数名の「後ろ」に型名を書く

関数名・引数・戻り値の順に記載

関数の2つ以上の引数が同じ型である場合には、最後の型を残して省略して記述できる。

func add(x, y int) int {
	return x + y
}

関数は複数の戻り値を返すことができる

package main

import "fmt"

func swap(x, y string) (string, string) {
	return y, x
}

func main() {
	a, b := swap("hello", "world")
	fmt.Println(a, b)
}

大文字(Public関数)・小文字(Private関数)

Go言語では、関数名や変数名が大文字で始まる場合、その関数や変数は「エクスポートされた」(Exported)と見なされ、他のパッケージからアクセス可能になる(Public関数)。これは、その名前がパッケージの外部に「公開」されていることを意味する。

逆に、小文字で始まる名前は、定義されたパッケージ内でのみアクセス可能(Private関数)。つまり、他のパッケージから利用したい関数や変数には大文字で始める必要がある。

構造体(Struct)

Go 言語における struct (構造体)は、フィールド(プロパティや属性とも言える)の集まりで、他の多くのプログラミング言語のクラスに類似した役割を果たす。ただし、Go の構造体はクラスと異なり、メソッドは構造体の定義の外部で定義され、構造体とメソッドは「レシーバ」を介して関連付けられる。

structのフィールドは、ドット( . )を用いてアクセスする。

レシーバを介したメソッドとの関連付け

Go ではメソッドは構造体と直接的には結びついていないが、構造体のインスタンス(またはポインタ)をメソッドの「レシーバ」として使用することで、クラスのような振る舞いを実現できる。

下記例では、Greet メソッドが Person 型のレシーバ p を使って定義されている。これにより、Person 型の各インスタンスに対して Greet メソッドを呼び出すことができる。

package main

import "fmt"

// Person 構造体の定義
type Person struct {
    Name string
    Age  int
}

// Person 構造体に対するメソッドの定義
func (p Person) Greet() {
    fmt.Println("Hello, my name is", p.Name)
}

func main() {
		// Person 構造体のインスタンスを作成
    p := Person{Name: "Alice", Age: 30}
    
    // ドット(.)を用いてメソッドにアクセス
    p.Greet()  // 出力: Hello, my name is Alice

    // ドット(.)を用いてフィールドにアクセス
    fmt.Println(p.Name) // 出力: Alice
    fmt.Println(p.Age)  // 出力: 30
}

ポインタレシーバ

ポインタレシーバーを使うと、、

続きは、こちらで記載しています。
https://kazulog.fun/dev/go-memorandom-func-type-struct-module/

Discussion