Java経験者から見たGo言語の文法一覧
※2020年当時書いたものを掲載しているので、Javaの言語仕様の理解が古いかもしれません。。。
ご容赦ください。
文法規則
出力
Main.java
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World");
}
}
main.go
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello World")
}
※fmtパッケージが必要
変数
型は最後に書く ※varは変数、letは定数
test.go
var c, python, java bool //c,python,javaは全てbool型
let swift bool = true //bool
★初期化すれば型を書かなくてよい
test.go
var i, j int = 1, 2 // 型を指定
var c, python, java = true, false, "no!" // 型を指定しない
fmt.Println(i, j, c, python, java) //1, 2, true, false, "no!"
★変数をまとめられる
test.go
var (
ToBe bool = false
MaxInt uint64 = 1<<64 - 1
z complex128 = cmplx.Sqrt(-5 + 12i)
)
const (
pi = 3.14
Big = 100
)
★初期化しなくても勝手に初期化してくれる
test.java
//Javaの場合
int i;
System.out.println(i);//コンパイルエラー
test.go
//Goの場合
var i int
var f float64
var b bool
var s string
fmt.Printf("%v %v %v %q\n", i, f, b, s)///0 0 false ""
★varを:=に省略できる。(ただし関数内のみ利用可。letでは使えない)
test.go
var i = 1
x := 0 // エラー
func main() {
let y := 3 // エラー
j,k := 2,3
fmt.Println(i, j, k)
}
関数
test.java
public int add(int x,int y){
return x + y;
}
test.go
func add(x int, y int) int {
return x + y
}
func add(x, y int) int {
return x + y
}
2つ戻り値を返せる
test.go
func swap(x, y string) (string, string) {
return y, x
}
a, b := swap("hello", "world")
fmt.Println(a, b)// "world" "hello"
nakedReturn
戻り値に名前を設定できて、戻り値を指定しなくていい
※ただし、難読性につながるため、内部の処理が短い場合にのみ推奨
test.go
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
for文
test.go
for i := 0; i < 10; i++ {
sum += i
}
while文
test.go
sum := 1
for ; sum < 1000; {
sum += sum
}
for sum < 1000 { //こっちの書き方でもOK
sum += sum
}
無限ループ
test.go
for {
}
if文
test.go
if x < 0 {
return sqrt(-x) + "i"
}
★if文の評価直前に変数宣言できる(ただし、if・elseのスコープ内のみ有効)
test.go
if v := math.Pow(x, n); v < lim {
return v
} else {
fmt.Printf("%g >= %g\n", v, lim)
}
return lim //ここではvは使えない
switch文
Javaと違い、caseに入ったらbreakされて止まる
test.go
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.\n", os)
}
defer
周囲の関数が返ってくるまで実行されない
test.go
defer fmt.Println("world")
fmt.Println("hello") // "hello world"
スタック形式で実行される last-in-first-out
test.go
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("done") // "9" ,"8" , "7", ...
Pointers
変数にポインタ(Javaでいうアドレス)を入れることができる
test.go
i, j := 42, 2701
p := &i // pのポインターにiのポインターを代入
fmt.Println(p) // 0xc00002c008
fmt.Println(*p) // 42
*p = 21 // pの値に代入
fmt.Println(i) // 21
p = &j // point to j
*p = *p / 37 // divide j through the pointer
fmt.Println(j) // see the new value of j
Javaの場合、intは値型、Integerはクラス型(アドレス)と決まっていたが、
Goでは型を指定しない限り、値型(例 p := i) なのか クラス型(例 p := &i)なのかわからない。
Struct
フィールドのコレクション
test.go
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
fmt.Println(v) // {1, 2}
v.X = 4
fmt.Println(v.X) // "4"
p := &v // ポインターをコピーすれば、シャローコピーできる
p.X = 1e9
fmt.Println(v) // 100000000, 2
p = &Vertex{1, 2} // &はstructのポインターが返される
fmt.Println(p) // &{1, 2}
}
ゴルーチン
力量が足りず、5分以内で説明できません。。。。申し訳ございません。