ゆるりのこと。

文系営業マンから新米データサイエンティストしています。

A Tour of Goのざっくりまとめ① <Packages, variables, and functions編>

A Tour of Goはこちらから行けます。あそべます。日本語もあります。
tour.golang.org


今回は、Packages, variables, and functionsページで勉強していました。
以下、自分なりのまとめ。

package内のexported nameについて

Goのpackageには、外部から参照できるExported Nameと、参照できないもの(Not Exported Name)がある。
それらの違いは、名前の最初が大文字(Public)か小文字(Private)かである。
mathパッケージにあるPiは大文字のため、Exported Nameであり、外部パッケージから参照することができる。
一方で、piとした場合は、小文字のため、外部から参照することができない。

// package mainからmathパッケージ内のPiを使う場合

package main

import (
	"fmt"
	"math"
)

func main() {
	fmt.Println(math.pi)
}
// Error: cannot refer to unexported name math.pi

func main() {
	fmt.Println(math.Pi)
}
// 3.141592653589793

関数の書き方

関数の書き方はいろいろあるけれど、変数名のうしろに型名を書く
返り値を指定する場合はさらにその後ろに書く。

package main

import "fmt"

// int型の引数x, yをとり、intのx+yを返すadd関数
func add(x,y int) int {
	return x + y
}

// string型の引数をとるx, yを反転させたy, xを返す (複数の返り値)
func swap(x, y string) (string, string) {
	return y, x
}

func main() {
	fmt.Println(add(42, 13)) // 55

	a, b := swap("hello", "world")
	fmt.Println(a, b) // worldhello

}


なお、なぜ型を宣言するかについては、こちらをみてね、ということで下記ページが紹介されているので、チラ見してみた。

blog.golang.org


ここでは、何故伝統的?であるC的記述法とGoのそれが違うのか、という疑問に答えるべく、Cの記法とともに紹介している。(Cを知らないひとはどうしたらいいの)
そもそもCをしらないので、正直サッパリなんですが、要するに関数で引数や返り値を宣言するときにめっちゃ複雑になりやすいやん?読みにくいやん?ってことっぽい(-A-)

// 例えばこういうの
int (*(*fp)(int (*)(int, int), int))(int, int)

Naked Return

関数内にて、返り値に変数名を指定する場合、返す値を明示しなくとも、returnだけでいいよ、というもの。
ただし関数が長いとReadbilityに影響するので、短い関数とかで使うこと推奨。

package main

import "fmt"

// 返り値にint型のx, yを指定している
func split(sum int) (x, y int) {
	x = sum * 4 / 9
	y = sum - x
	return // returnだけで先に指定したint型のx, yを返す
}

func main() {
	fmt.Println(split(17)) // 7, 10
}

変数のつくりかた

「var」を使う場合と、「:=」であらわすShort declarationsを使う場合がある。
Short declarationsは関数の外では使用できないので注意。

var x int
var y int = 100 // 初期化子(Initializer). この場合、最初から100という値をyに与えている.
var y = 100 // Initializerの場合、型は省略可

z := 1000 // Short variable declarations
func main(){
	x = 10
	fmt.Println(x) // 10
	fmt.Println(y) // 100
}

////////////////////////////////////////////////////////////////

test := "test" //関数外では使えないのでError: non-declaration statement outside function body

func test() string {
	x := "test" //関数内では使える
	return x
}

func main() {
	fmt.Println(test()) // test

Zero Values

変数ついでに、変数に初期値を与えない場合、Zero Valuesといわれる初期値?が勝手に与えられる。
型によって違うが、int型は0, bool型はfalse, string型は""(blank)など。

型変換・型推論

Goの型変換は非常に明快で、基本的には変換したいタイプ内に変換元の値を入れるだけ。
Pythonみたいに楽でいいですね。
ただし、Pythonでできるような、異なる型での演算等はコンパイルエラーとなる。
バグの原因となりやすいようです。int32 と intでもダメ。(仮にintがint32-bit型だとしても...)
つまり、明示した型や型推論されたもの同士でないといけない、っとことかな。

package main

import "fmt"

func main() {
	x := 12
	y := float64(x) // int -> float64に変換
	fmt.Printf("%T %v\n", x, x) // int 12
	fmt.Printf("%T %v", y, y) // float64 12
}

なお、ここでx := 12と型宣言なしで変数をつくった場合、型推論をしてくれるので勝手にint型としてくれている。
これは初期値に応じて変えてくれる。

定数 Constant

定数は const をつかってあらわす。
Short declaration「:=」を使って宣言はできない。
また、constが使えるのは文字・文字列・boolean・数値だけ。

const同士からconstをつくることも可能。

package main

import "fmt"

const Pi = 3.14
const Pi := 3.14 // error: unexpected :=, expecting =

func main() {
	const World = "世界"
	fmt.Println("Hello", World)
	fmt.Println("Happy", Pi, "Day")

	const Truth = true
	fmt.Println("Go rules?", Truth)
}

また、goではconstを使う場合、型を宣言する必要はないそうです。なぜなら、毎回変換する際に面倒だから(?)
定数に関してはこちらの記事が勉強になりました。
qiita.com


元記事はこちら。
blog.golang.org

/* */