型宣言
type long float64
type large float64
型変換
var lg long = 333.3;
large(lg)//型変換
メソッド
オブジェクト指向のメソッド
オブジェクト指向プログラミングは、クライアントがオブジェクト内部表現に直接アクセスする必要がないようにするために、個々のデータ構造の特性と操作を表現するためのもの
Golangのメソッド
Goにおいてのオブジェクトはメソッドを持つ単なる変数であり、メソッドは特定の型に関連付けられた関数。
(参考:https://qiita.com/pei0804/items/2a3010df39623fadc3c6)
メソッドの定義方法
func (レシーバー 型) 関数名 (引数) 戻り値の型 {
}
関数を変数に代入することもできる
package main
import (
"fmt"
"math/rand"
)
type kelvin float64
func fakeSensor() kelvin {
return kelvin(rand.Intn(151) + 150)
}
func realSensor() kelvin {
return 0
}
func main() {
sensor := fakeSensor
// 型推論を使用しないとき
var sensor func() kelvin
fmt.Println(sensor())
sensor = realSensor
fmt.Println(sensor())
}
このときのsensor
は関数型
関数型
宣言例
func(int, int) int
クロージャ
- 関数を処理中に、その場で作る必要があるとき使用される
クロージャの一番簡単な例
package main
import "fmt"
// クロージャーの実装
func addGen2() (func() int) {
x := 0
return func() int {
x++
return x
}
}
func main() {
// addGen2は関数が戻り値なので変数に代入する
add2 := addGen2()//x := 0が実行される
fmt.Println(add2())
fmt.Println(add2())
fmt.Println(add2())
}
(参考:https://golangstart.com/go_closure/#toc3)
-
add2
を参照し続ける限りx
は保持され続ける - add2()は無名関数部分が実行される()
配列
package main
import (
"fmt"
)
func main() {
var planets [8]string//配列の要素数と型の宣言
planets[0] = "水星"
planets[1] = "金星"
planets[2] = "地球"
planets[3] = "火星"
for i := 0; i < 4; i++ {
fmt.Println(planets[i])
}
}
複合リテラル表記👇
planets2 := [...]string{
"水星",
"金星",
"地球",
"火星",
}
for i := 0; i < len(planets2); i++ {
fmt.Println(planets2[i])
}
配列はDeep Copyされる
planets2 := [...]string{
"水星",
"金星",
"地球",
"火星",
}
planets3 := planets2//参照は共有されない
スライス
planets := [...]string{
"水",
"金",
"地",
"火",
"木",
"土",
"天",
"海",
}
terrestrial := planets[0:4]
gasGiants := planets[4:6]
iceGiants := planets[6:8]
fmt.Println(terrestrial, gasGiants, iceGiants)
iceGiantsM2 := planets[6:8]
iceGiantsM2[1] = "Poseidon"
planets3 := []string{//something}
fmt.Println(iceGiantsM2)
- 配列が直接使用されることはほとんどない。スライスが使用される
- いきなりスライスを作ることも可能
samples := []string{"a", "b", "c", "d", "e", }
裏では基底配列が存在し、5つの要素を持つ配列が宣言され、その全部の要素を見るスライスが作られる
- スライスに要素を追加する
dwarfs := []string{"Ceres", ""}
make 関数
スライスの事前割り当て
👇の例ではappendで容量が足りなくて臨時でコピーと割り当てをする必要がない
dwarfs := make([]string, 0, 10)
dwarfs = append(dwarfs, "Ceres", "Pluto", "Haumea", "Makemake", "Eris")
可変長引数
package main
import (
"fmt"
)
func terraform(prefix string, worlds ...string) []string {
// ...は可変長引数を使用する合図
newWorlds := make([]string, len(worlds))
for index, value := range worlds {
newWorlds[index] = prefix + " " + value
// rangeの第一引数は"index番号"、第二引数はindex番号に対応した配列の値
}
return newWorlds
}
func main() {
twoWorlds := terraform("New", "Venus", "Mars")
fmt.Println(twoWorlds)
}
map
package main
import (
"fmt"
)
func main() {
temperature := map[string]int{
"Earth": 15,
"Mars": -65,
}
temp := temperature["Earth"]
fmt.Println(temp)
temperature["Venus"] = 455
fmt.Println(temperature)
}
マップに存在しないキーをアクセスしたら、結果は値の型(int)のゼロ値になる
map
のvalue
が0のときと、map
にkey
がないときは,ok
構文を用いる
if moon, ok := temperature["Moon"]; ok {
// 内容
} else {
// 内容
}
出現頻度を出力するプログラム
package main
import (
"fmt"
)
func main() {
temperature := []float64{
-28.0, 32.0, -31.0, -29.0, -23.0, -29.0, -28.0, -33.0,
}
frequency := make(map[float64]int)
for _, t := range temperature {
frequency[t]++
}
for t, num := range frequency {
fmt.Printf("%+.2f の出現は%d回です\n", t, num)
}
}