Open IkumaTadokoro opened 2 years ago
次は基本構文編
Goは静的型付け言語 変数宣言
var n int = 100
var n = 100 // 型推論
n := 100 // 関数ないのみで利用可能
var (
n = 100
m = 200
)
int型がint, int8, int16とビット単位である。
型ごとのデフォルト値「ゼロ値」が決まっている。 お〜GoLand側で型推論できる場合は消すようにサジェスチョンが出るのか。
定数宣言
const n int = 100
お〜文字列はシングルクォーとしか使えないんだな。
iota、とりあえずいい感じの連番と理解
FizzBuzzやったので、次は関数
なるほど、複数のデータ型があつまると、コンポジット型だと。スライス型ってのは面白いな。名前の意味はわかるけど今までの言語では見ていないかも。
お〜配列の要素数が変更できない!いいね〜
とりあえず「全く知らない」から、FizzBuzzできるくらいまでには進化。
https://zenn.dev/nobonobo/articles/e0af4e8afc6c38b42ae1
とりあえずわかるのは「Goに入ってはGoに従え」は本当にそうした方がいい。Ruby→JavaScriptに比べてだいぶ経路が違う。 書けるようになっても、ちゃんとやらないとGo本来の実力を引き出せない。なんでそう書くのかを言語仕様と照らし合わせないとダメ
Goのツールチェーンに対して感じる便利さはDenoに近いものがある
import "fmt"
import "math"
// factored import statement: こっちが一般的
import (
"fmt"
"math"
)
大文字だと自動的に外部パッケージに公開される。逆に小文字だと公開されない。
func add(x int, y int) int {
return x + y
}
https://go.dev/blog/declaration-syntax
Goの型宣言。C以外の言語では名前: 型宣言
となることが多いが、Goでは簡潔さをめざしコロンを削除したとのこと。
// 型が同じ場合は宣言を最後だけにすることができる。
func add(x, y int) int {
return x + y
}
// 複数の戻り値を返すこともできる
func swap(x, y string) (string, string) {
return y, x
}
// 戻り値に名前をつける: named return value
// 名前をつけた戻り値の変数を使うと、return ステートメントには何も書かずに戻すことができる
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
// Variables
var isExpensive bool
var i, j int = 1, 2
package main
import "fmt"
func main() {
k := 3
fmt.Println(k)
}
var i int = 24
// 型変換(Type Conversions)
var f float64 = float64(i)
package main
func main() {
var i int
j := i // jはintとして推論される(Type Interface)
}
// 定数宣言
// 定数は`:=`で宣言できない。
const Pi = 3.14
// 型のない数値の定数は値に応じて必要な型をとる
const Big = 1 << 100
ここまででPacakages, varibales, and functionsが終了
Forループ
package main
import "fmt"
func main() {
sum := 0
// 条件部分のカッコは省略できる。中括弧を省略することはできない。
for i = 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
package main
import "fmt"
func main() {
sum := 1
// 初期化処理と後処理ステートメントの記述は任意
fot sum < 1000 {
sum += sum
}
fmt.Println(sum)
}
package main
import "fmt"
func main() {
// 無限ループ
for {
fmt.Println("hoge")
}
}
import "fmt"
// if文も条件部分のカッコを省略することができる
if x < 0 {
fmt.Println("minus")
}
import "math"
// ifステートメントの中では簡単なステートメントを書くことができる
if v := math.Pow(x, n); v < lim {
return v
}
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Print("Go runs on")
// breakは不要
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
fmt.Printf("%s.\n", os)
}
}
pakage main
import "fmt"
func main() {
// defer: deferへ渡した関数の実行s、呼び出し元の関数の終わりまで遅延させるもの
defer fmt.Println("world")
fmt.Println("hello")
}
// この場合、main()が呼び出し元になるので、その関数の終わり(つまり"hello"が表示されるまで)呼び出されることはない
deferが複数ある場合には、deferされた関数はスタックされ、LIFOで呼び出される。
ここまででFlow Control statements: form if, else, switch and deferが完了
ここからPointerか。今日中には終わらせるけど、じっくりやっていくぞ。
Goはポインタを扱います。ポインタは値のメモリアドレスを指します。
なんとなくわかるけど、なんのために使うのかわかっていない。
変数T
のポインタは、*T
型で、ゼロ値はnil
である。あれ、そういやnull
じゃなくてnil
なんだな。
var p *int
&
オペレータでそのオペランドへのポインタを引き出す。
i := 42
p = &i
*
オペレータは、ポインタの指す先の変数を示す。
i := 42
p = &i
fmt.Println(*p)
これを"dereferencing"または"indirecting"と呼ぶそうな。確かにそんな感じはする。
// 構造体
type Hoge struct {
X int
Y int
}
func main() {
hoge := Hoge{1, 2}
fmt.Println(hoge.X)
hoge.X = 4
fmt.Println(hoge.X)
}
type Vertex struct {
X, Y int
}
var (
v1 = Vertex{X: 1} // これがName構文で、フィールドの一部だけを指定することができる
)
[n]T型は、型Tのn個の変数の配列を表す。
var array [2]string // 要素数2この配列
配列の要素数を変えることはできない。配列は固定長だが、スライスは可変長。型[]Tは型Tのスライス
var slice []int // int型のスライス
primes := [4]int{2, 3, 5, 7}
s = primes[0:2]
スライスはスライスという独自なものではなくて、配列の部分列。スライスの要素を変更すると、元となる配列が変更される。 スライスはコロンで区切られたインデックスによって元の配列の部分を指定する。半開区間なので、上限の方は含まない。
スライスする時の下限と上限をそれぞれ省略した場合には、デフォルトの値が採用される。下限は配列の最初で、上限は配列の最後。
スライスには長さと容量の2つの属性がある。長さはスライス自体の長さで、容量はスライスの最初の要素から数えて元となる配列の要素数
スライスのゼロ値はnil。
組み込みのmake
関数を使ってスライスを作成する。
package main
import "fmt"
func main() {
// ゼロ化された配列を割り当て、その配列を指すスライスを返す
a := make([]int, 5)
// ゼロ化された配列を割り当て、その配列かつ指定した容量のスライスを返す
b := make([]int, 0, 5)
}
rangeはforループに利用し、スライスやマップを一つずつ反復処理するために使用する。
import "fmt"
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
func main() {
// indexとvalueを返している
for i, v := range pow {
fmt.Printf("3**%d = %d\n", i, v)
}
}
必要ない値は_
で捨てることができる。
とりあえずBasicまでは終わった...。
とりあえずソースコードを落としてみた。
https://github.com/chromedp/pdlgen
全くわからないという感じではないけれど、読むのに時間かかりそう。このコードを読みながらGoの文法を定着させていきたい。
Goやっていくぞ。読めるようになるにもどういう知識が必要かわからないので、
https://docs.google.com/presentation/d/1RVx8oeIMAWxbB7ZP2IcgZXnbZokjCmTUca-AbIpORGk/edit#slide=id.g4f417182ce_0_80
これをやっていく