はじめに
こんにちは。
ARISE analyticsのエンジニアの井上です。
弊社ARISE analyticsの技術ブログに先日Goについての記事を投稿しました。
そのページはこちら
この記事ではサーバーサイド開発として使われるPHP, Javaと比較して
Goの書き方とパフォーマンスについて語りました。
ベンチマークの比較を行う上で、なるべく処理方法を共通とするために
Goらしさを排除した書き方をしました。
本記事ではブログで紹介したGoらしくないソースコードを
筆者が考えるGoらしいソースコードを紹介します。
Goらしいソースコード
では先にGoの特徴を踏まえたコードを見ていきましょう。
まずはバブルソートの例です
package main
import (
"fmt"
"math/rand"
"time"
)
type intSlice []int
func main() {
rand.Seed(time.Now().UnixNano())
array := make(intSlice, 0, 1000)
for i := 1; i <= 1000; i++ {
array = append(array, i)
}
array.shuffle()
start := time.Now()
array.bubbleSort()
fmt.Println(time.Since(start).Microseconds())
}
func (s intSlice) shuffle() {
rand.Shuffle(len(s), func(i, j int) {
s[i], s[j] = s[j], s[i]
})
}
func (s intSlice) bubbleSort() {
for i := 0; i < len(s); i++ {
for j := 1; j < len(s); j++ {
if s[j-1] > s[j] {
s[j-1], s[j] = s[j], s[j-1]
}
}
}
}
それではここからはGoの特徴を4つ紹介します
特徴
type
typeキーワードは既存の型、型リテラルに別名をつけることができます。
type intSlice []int
はintSlice
はint型のスライスである、と宣言を表します。
この特徴単独ではただ別名で型を宣言するだけになりますが、
宣言した型にメソッドを追加することができます。
レシーバ
Goは型にメソッドを追加でき、メソッドを追加する先のことをレシーバと言います。
func (s intSlice) shuffle()
このように書くことでintSlice
はshuffleメソッドを持ち
intSlice型のarrayで
array.shuffle()
と記述するとshuffleを呼び出すことができます。
スライスのメモリ管理
Goはスライスという可変長の配列のような型で宣言時にメモリを確保します。
var slice []int
とした場合は要素数0のため容量が0のスライスになります。
スライスに対してappendをして確保した容量を超えた時に
再度メモリを確保するため、使う長さが決まっている場合は先にその分のメモリを確保すると効率的になります。
スライスで長さを指定するためには組み込み関数のmake
を使え
array := make(intSlice, 0, 1000)
と記述すると長さ1000のintSliceをarrayに宣言と代入ができます。
多値返却
Goは複数の値を返却できます。
そのためソートでj-1番目とj番目を入れ替えるときには
s[j-1], s[j] = s[j], s[j-1]
と表現できます。
最後に
我々ARISE analyticsはモダンな技術を取り入れて開発をしています。
興味のある方はぜひ我々のHPを御覧ください。