はじめに
こんばんは。
今年も早くも10ヶ月たって、全く成長してない僕です。
今年のはじめに決めた目標はブレブレになってしまって、どれもこれも中途半端という不甲斐ない結果になっております。
まぁ嘆いてもしょうがないので、今月から気を引き締めて、またやっていこうと思います。
とりあえず今年10月から来年も踏まえて、Go、Python、Javascriptの3つを重点的に勉強しようと思ってます。
比率的には
Go: 4
Javascript: 4
Python: 2
といった比率で勉強しようと思ってます。
なんでこの比率かというと、
Goは、もともと勉強したいというのがあったのですが、知人からGoの案件を紹介してもらったことがきっかけでした。その時は実務経験も勉強もしてない状態だったのでスキル的にミスマッチだったので断ったのですが、せっかくのお誘いを自分のスキル不足で台無しにしてしまうのが悔しかったので、やろうと思いました。
Javascriptは、今年の目標の一つで、フロントエンド側の知見を貯めるというのに続いています。何回かReactやVue.jsの勉強やりましたが、実践で使えるほどの知見は全然溜まってないので、もう少し踏み込んで勉強をしていこうと思っています。FWはReactに絞って勉強しようと思ってます。
Pythonに関しては、唯一成長したというか、調べつつ書けるようになってきている実感があるので、ある程度勉強は続けていこうと思いこの比率です。
あとはSwiftも個人的にやってた時期があるので、どうにか滑り込ませたいなと思ってますが、時間的に厳しいかも。。。
とりあえず今回はGo言語の勉強ですね。
大昔にTour of Goやったくらいなので、さっぱり忘れてます。
さっそくいきます。
やってみた
package main
import "fmt"
func main() {
fmt.Println("Hello World")
}
go build goファイルで、ビルドされたバイナリが作成されて、そのバイナリを実行すれば、Hello Worldが表示される
$ go build hello.go
$ ./hello
Hello World
$ ls -la
total 3920
drwxr-xr-x 4 kojirock staff 128 10 3 00:07 .
drwxr-xr-x 21 kojirock staff 672 10 2 23:54 ..
-rwxr-xr-x 1 kojirock staff 1999368 10 3 00:07 hello
-rw-r--r-- 1 kojirock staff 72 10 3 00:01 hello.go
go run goファイル名で、ビルドと実行が同時に行われるけど、対象のバイナリは作られない
$ go run hello.go
Hello World
$ ls -la
total 8
drwxr-xr-x 3 kojirock staff 96 10 3 00:03 .
drwxr-xr-x 21 kojirock staff 672 10 2 23:54 ..
-rw-r--r-- 1 kojirock staff 72 10 3 00:01 hello.go
制御構文
- 繰り返し処理はforのみ、while, foreach, do whileなどはない。でもforのみで再現できる。
for i:=0; i < 5; i++ {
fmt.Println(i)
}
count := 0
for count < 10 {
fmt.Println(count)
count++
}
data_list := map[string]int{
"aaa": 10,
"bbb": 20,
"ccc": 30,
}
for key, value := range data_list {
fmt.Println("key => ", key, " value => ", value)
}
衝撃だったけど、forしかないことで逆にシンプルだと思った。
break
continue
は通常通り使えるとのこと。
関数とか変数とか
- 頭文字が小文字のメンバは、同パッケージ内からのみアクセス可能
- 頭文字が大文字のメンバは、別パッケージからもアクセス可能
- 基本的に変数はvar, 関数はfuncで定義
- 変数は型推論があるので、型の省略も可能
- ローカル変数に関しては、型を指定できず、宣言も
:=
で行う
- const定義も可能で、かつ、型を持たない定数が可能。また、関数内でも定義できる。
- iotaという列挙型みたいなものをconstでは指定できる。
テストのために自分で作成したローカルパッケージを作成してimportする
test_01.go
package package_test
func All() {
aaa()
bbb()
ccc()
ddd()
println(bbbvar)
println(dddconst01)
}
func aaa() {
println("aaa")
}
test_02.go
package package_test
var bbbvar = 100
func bbb() {
println("bbb")
}
test_03.go
package package_test
func ccc() {
cccvar := 200
println("ccc")
println(cccvar)
}
test_04.go
package package_test
const dddconst01 = "dddconst01"
func ddd() {
const dddconst02 = 2
println(dddconst02)
println("ddd")
}
hello.go
package main
import "./package_test"
const (
Red = iota
Blue
Yellow
)
func main() {
package_test.All()
println(Red)
println(Blue)
println(Yellow)
}
$ go run hello.go
aaa
bbb
ccc
200
2
ddd
100
dddconst01
0
1
2
いろんな型
配列型
固定長の配列を作成する。
var data_array [3]int
var data_array = [3]int{10, 20, 30}
var data_array = [...]int{10, 20, 30}
var data_array = [...]int{0: 10, 1: 20, 2: 30}
スライス型
可変長の配列を作成する。
var data_array []int
var data_array = []int{10, 20}
var data_array = []int{10, 20}
data_array = append(data_array, 30)
println(data_array[2])
マップ型
phpでいう連想配列かな
var data_array = map[string]int{"aaa": 10, "bbb": 20}
data_array["ccc"] = 30
型宣言(type)
独自の型を作成できる。
reflectパッケージの TypeOf()
で指定のものがなんの型がわかる。
package main
import "fmt"
import "reflect"
type TestType int
var param1 TestType = 100
var param2 int = 200
func main() {
fmt.Println(param1)
fmt.Println(param2)
fmt.Println(reflect.TypeOf(param1))
fmt.Println(reflect.TypeOf(param2))
}
$ go run type.go
100
200
main.TestType
int
学生時代C言語やってたときにこんな事やった記憶があるような気がする。
構造体(Struct)
Goはクラスがないから構造体。めちゃ懐かしい。
- math/randパッケージを使用して乱数を生成している
- strconvパッケージを使用して、数値から文字列へのキャストをこなっている
package main
import (
"fmt"
"math/rand"
"strconv"
"time"
)
type Player struct {
life int
attack int
luck int
}
func (p *Player) is_die() bool {
return p.life == 0
}
func (p *Player) damege(point int) {
p.life -= point
if p.life < 0 {
p.life = 0
}
}
type Enemy struct {
life int
attack int
luck int
}
func (e *Enemy) is_die() bool {
return e.life == 0
}
func (e *Enemy) damege(point int) {
e.life -= point
if e.life < 0 {
e.life = 0
}
}
func main() {
var player Player
var enemy Enemy
player.life = 10
player.attack = 1
player.luck = 5
enemy.life = 10
enemy.attack = 1
enemy.luck = 5
for {
player_attack_offet := 0
enemy_attack_offet := 0
rand.Seed(time.Now().UnixNano())
if player.luck >= rand.Intn(10) {
player_attack_offet++
}
if enemy.luck >= rand.Intn(10) {
enemy_attack_offet++
}
enemy.damege(player.attack + player_attack_offet)
fmt.Println("プレイヤーの攻撃!敵に" + strconv.Itoa(player.attack+player_attack_offet) + "のダメージを与えた!")
player.damege(enemy.attack + enemy_attack_offet)
fmt.Println("敵の攻撃!プレイヤーに" + strconv.Itoa(enemy.attack+enemy_attack_offet) + "のダメージを与えた!")
if player.is_die() == true {
fmt.Println("敵の勝ち!")
break
} else if enemy.is_die() == true {
fmt.Println("プレイヤーの勝ち!")
break
}
}
}
$ go run struct.go
プレイヤーの攻撃!敵に2のダメージを与えた!
敵の攻撃!プレイヤーに1のダメージを与えた!
プレイヤーの攻撃!敵に2のダメージを与えた!
敵の攻撃!プレイヤーに1のダメージを与えた!
プレイヤーの攻撃!敵に1のダメージを与えた!
敵の攻撃!プレイヤーに1のダメージを与えた!
プレイヤーの攻撃!敵に1のダメージを与えた!
敵の攻撃!プレイヤーに2のダメージを与えた!
プレイヤーの攻撃!敵に2のダメージを与えた!
敵の攻撃!プレイヤーに1のダメージを与えた!
プレイヤーの攻撃!敵に2のダメージを与えた!
敵の攻撃!プレイヤーに1のダメージを与えた!
プレイヤーの勝ち!
ダラダラと長くなってしまったけど、こんな感じなのかな?
ポインタ型
C言語でお馴染みのポインタ。確か僕が挫折したのがポインタ。
ただ、ロジックの見通しよくするためには、必要だし、苦手意識は克服しなければ。
func main() {
var player Player
var enemy Enemy
player.life = 10
player.attack = 1
player.luck = 5
enemy.life = 10
enemy.attack = 1
enemy.luck = 5
for {
battle(&player, &enemy)
if player.is_die() == true {
fmt.Println("敵の勝ち!")
break
} else if enemy.is_die() == true {
fmt.Println("プレイヤーの勝ち!")
break
}
}
}
func battle(player *Player, enemy *Enemy) {
player_attack_offet := 0
enemy_attack_offet := 0
rand.Seed(time.Now().UnixNano())
if player.luck >= rand.Intn(10) {
player_attack_offet++
}
if enemy.luck >= rand.Intn(10) {
enemy_attack_offet++
}
enemy.damege(player.attack + player_attack_offet)
fmt.Println("プレイヤーの攻撃!敵に" + strconv.Itoa(player.attack+player_attack_offet) + "のダメージを与えた!")
player.damege(enemy.attack + enemy_attack_offet)
fmt.Println("敵の攻撃!プレイヤーに" + strconv.Itoa(enemy.attack+enemy_attack_offet) + "のダメージを与えた!")
}
$ go run struct.go
プレイヤーの攻撃!敵に1のダメージを与えた!
敵の攻撃!プレイヤーに1のダメージを与えた!
プレイヤーの攻撃!敵に1のダメージを与えた!
敵の攻撃!プレイヤーに2のダメージを与えた!
プレイヤーの攻撃!敵に2のダメージを与えた!
敵の攻撃!プレイヤーに2のダメージを与えた!
プレイヤーの攻撃!敵に1のダメージを与えた!
敵の攻撃!プレイヤーに2のダメージを与えた!
プレイヤーの攻撃!敵に2のダメージを与えた!
敵の攻撃!プレイヤーに2のダメージを与えた!
プレイヤーの攻撃!敵に1のダメージを与えた!
敵の攻撃!プレイヤーに2のダメージを与えた!
敵の勝ち!
おわりに
とりあえず今日はここまでです。
やってみて思ったけど、すごくシンプルで覚えることも少なそうだけど、シンプルだからこそ、設計力が求められそうな感じだと思いました。
でも、Go言語でガッツリwebサービス作るっていうよりはAPI的な立ち位置で使ってるケースが多いからそこまで大規模に使うものでもないのかもしれません。
でもGoのフレームワークもあるみたいだし、せっかくだからwebサービス作る方向で勉強してみようとおもいます。
おすすめの本などあれば教えてください。
そういえば、最近やっとsublimeからvscodeに乗り換えたんですけど、すごくいいですね。同じElectronで作られてるAtomとはえらい違いです。
php or jsはphpstorm
pythonはspyder
それ意外のものに関してはvscode
って感じで定着しそうです(もはやpythonもvscodeになりそう)
おやすみなさい。