c++と比較した時のgo。印象を箇条書きで
クラスという概念がない?関数と構造体だけで頑張る感じなのか?かなりcに近い言語っていうイメージだな。構造体があれば言うてもクラス作れるからな。
しかしソースコードを見てみると、メソッドみたいにアクセスしてるんやが?どういうことや?
package datastruct
import "fmt"
// Queue implementation
type Queue struct {
data []int
size int
}
// NewQueue instantiates a new queue
func NewQueue(cap int) *Queue {
return &Queue{data: make([]int, 0, cap), size: 0}
}
// Push adds a new element at the end of the queue
func (q *Queue) Push(n int) {
q.data = append(q.data, n)
q.size++
}
// Pop removes the first element from queue
func (q *Queue) Pop() bool {
if q.IsEmpty() {
return false
}
q.size--
q.data = q.data[1:]
return true
}
// Front returns the first element of queue
func (q *Queue) Front() int {
return q.data[0]
}
// IsEmpty checks if the queue is empty
func (q *Queue) IsEmpty() bool {
return q.size == 0
}
// String implements Stringer interface
func (q *Queue) String() string {
return fmt.Sprint(q.data)
}
import (
"fmt"
"testing"
)
func TestQueue(t *testing.T) {
queue := NewQueue(10)
fmt.Println(queue)
if !queue.IsEmpty() {
t.Fatalf("True is expected, but %v\n", queue.IsEmpty())
}
queue.Push(10)
fmt.Println(queue)
queue.Push(1)
fmt.Println(queue)
queue.Push(-5)
fmt.Println(queue)
if queue.IsEmpty() {
t.Fatalf("False is expected, but %v\n", queue.IsEmpty())
}
if queue.Front() != 10 {
t.Fatalf("10 is expected, but %v\n", queue.Front())
}
queue.Pop()
fmt.Println(queue)
if queue.Front() != 1 {
t.Fatalf("1 is expected, but %v\n", queue.Front())
}
queue.Pop()
fmt.Println(queue)
if queue.Front() != -5 {
t.Fatalf("-5 is expected, but %v\n", queue.Front())
}
queue.Pop()
fmt.Println(queue)
if !queue.IsEmpty() {
t.Fatalf("True is expected, but %v\n", queue.IsEmpty())
}
}
なるほど、cっぽい感じで、構造体とそれを操作する関数に分かれているけど、関数はメソッドのように構造体に紐づく。 cでは、関数に構造体のポインタを渡さないと構造体に変更を加えることができなかったけど、goでは構造体か関数を呼び出せるやんか。んで、この構造体に紐づけられているメソッドのような関数の定義方法はgo特有の定義方法になっているって話ですよね。
めちゃめちゃライブラリが少ないイメージだな。c++でいうところのmapとvectorしかないね。ちなみにvectorはgoではスライスって言いますね。
エントリポイントは相変わらずmainです。
直接実行とコンパイル実行の二つの実行形態を持つ。 go run main.go / go build.
packageとは? c/c++では、.hppに宣言、引数、戻り値を書いて、.cppに処理内容を書いていたよね。 んで、コンパイラは、.hにかかれている関数の入出力関係だけを見て、アセンブリして、最後にリンカーが関数の処理の部分をくっつける感じだったけど、goはわかりませんわね。packageって何の単位なの?って話。c/c++はファイル単位でincludeしていたけどねー。main packageは絶対に必要って話ですよ。で、処理をまとめてpackageにするんでしょうけど、packageを複数のファイルにまとめることも可能みたいですね。この辺は少しわかりづらいですか。
interfaceとは?
スレッドの生成(厳密にはgoroutine)がめちゃめちゃ簡単にできるという話。 なんか知らんけど、システムコールを呼び出してないらしくてさ、まあとにかくめちゃめちゃ高速らしい。まあ、言うてもスレッドを生成する時のオーバーヘッドが大きいだけで、スレッドプールとかを作っておけばオーバヘッドもほとんどないんだけどね。
ポインタがフツーに使える クラスがないけど、構造体があって、参照はないけどポインタがあるってのがcっぽさを増長させているね。気を付けてほしいのは、
int* a = malloc(sizeof(int)*8);
とかがcだけど、
var a *int
みたいに、アスタリスクの順番がちょいと紛らわしいってところかな。 まあ、参照渡しと値渡しの違い位はわかるので大丈夫かな。
2次元配列はいったいどうやって実現するのですか?
makeってなに?
charはないの?
結論: 他の言語を学べば学ぶほどc++にかなう言語はないのではないかと思ってしまう。いやフツーにc++が一番強くね? 静的型付けでテンプレートっていう概念があるから、めちゃめちゃ複雑なデータ構造でも簡単に作れるって話になるのよ。実行速度も申し分なし。まあメモリ管理がむずいって話は少しあるが、この辺は頑張れば行ける。
で、わざわざgoをやる意味を感じられなかったので、いいかな。 c++でかなり小回りが利く処理ができるし、websocketで外部との通信もできるし、msyqlとの接続もできる。バックエンドで複雑な処理が必要なところはc++で、フロントエンドからバックエンドへのエントリーポイントはnode.jsでやればいいかなって感じですわ。pythonでデータ分析もできるしね。
もう少しちゃんと考える
そうとも行ってられなくなってきた。2023/09/06って感じですね。まあ少し頑張っていきましょう。 ちょっと実際に書いてみて思ったことなんですけど、これ、cの強化版ですわ。なかなか書きやすい。スピード感を持ってかけるという意味ではかなりいい気がしている。