ホームページ  >  記事  >  バックエンド開発  >  これが私が 2 週間で Go について学んだことのすべてです。

これが私が 2 週間で Go について学んだことのすべてです。

Barbara Streisand
Barbara Streisandオリジナル
2024-10-31 04:27:02690ブラウズ

This is all what I

何か新しいことを学ぶ必要があるとき、あなたはどのようなアプローチをとりますか?非常に具体的なものがあるので、Golang を学習しながらもう一度テストしてみました!

話したい内容が多すぎますが、ここでの私の目的は、私が役に立ったこと、そして特に時間をかけて適切に学習したことをリストすることです。

目次

  • 1.プロローグ
  • 2. CLI の紹介
    • 2.1 CLI: mod に移行
    • 2.2 CLI: 実行する
  • 3. 異なる構文の比較
    • 3.1 構文: クラス/構造体と API のカプセル化
    • 3.2 構文: インターフェイスの実装は FUC* として奇妙です
  • 4. Stdlib: 間違いなく素晴らしいツールキット
    • 4.1 パッケージ: プリミティブ型
    • 4.2 パッケージ: 便利なもの
  • 5. Go のテストはとても簡単です
    • 5.1 テスト: 基本的なテスト
    • 5.2 テスト: Jetbrains ボイラープレート
    • 5.3 テスト: テストの実行
  • 6.循環インポートに注意してください
  • 7.これも延期、あれも延期…しかし、延期とは何ですか?
  • 8.初心者のためのエラー管理
  • 9.結論:低遅延コーディングチャレンジ

1. プロローグ

ここ 2 週間、私は Golang を使って小さなアプリケーションを学び、構築してきました。現時点では、多くのライブストリームを通じてほぼ 50 時間のコードを作成しており、以前は言語に関していくつかの小さな問題を抱えていたことを学ぶことができて、非常に素晴らしいものでした。

この 2 週間の旅で私は次のことを行いました:

  • 小さくて本当にシンプルなシェル
  • Redis 基本実装
  • HTTP 1.1 プロトコルの実装
  • DNS サーバーの実装
  • そして、本当に素晴らしい会社への就職テスト (この記事の最後でご覧いただけます)。

これもすべて、上司が ScyllaDB の PoC とデモに取り組むために新しいテクノロジーを学ぶように再び私に頼んだためです... 私はその決定にあまり満足していませんでしたが、まあ、それは私の仕事です。

この 1 年間、私は Rust を勉強してきました。おそらく私にとってはまだ複雑すぎるかもしれませんが、本当に素晴らしい概念をいくつか学んだので、Go への切り替えは魔法のようにうまくいきました。

この記事では、学習フローをスピードアップするためのヒントとアドバイスをいくつか紹介します。

2. CLI の紹介

私は PHP 開発者で、これまでに作成された中で最高の CLI (はい、Artisan です) には慣れていますが、開発者としての歩みを通じて、素晴らしいプロジェクトを経験してきましたが、その多くは次のとおりです。

  • 貨物 (錆)
  • NPM (JS)
  • コンポーザー (PHP)
  • など...

Go 環境に到達すると、それは大きな問題として始まりました。少なくとも私にとっては、ツールとドキュメントの点で Golang の開発者エクスペリエンスははるかに優れている可能性があります。これを考慮して、最初に必ず学習する必要がある 3 つのコマンドを最初に実行することにしました。

覚えておいてください: これは私自身の説明を含む単なるウォークスルーです。詳細な情報が必要な場合は、ドキュメントを開いてください:)
また、go docs は最悪です、誰かそこに構文ハイライトを入れてください

2.1 CLI: go mod

アプリケーションをモジュール化したいか、整理された環境を構築したいかによって、最初はこれが最も便利なコマンドになります。

go mod コマンドは、プロジェクト内のすべての依存関係を管理し、使用されなくなったものはすべて自動削除します。

まず、新しい空のフォルダー内で、 go mod init を使用してプロジェクト内の新しいモジュールを初期化しましょう:

mkdir go-fodase
cd go-fodase

# go mod init <module-name>
go mod init github.com/danielhe4rt/go-fodase

これにより、go.mod という名前の新しいファイルがプロジェクト ルートに作成されます。これは基本的に現時点での内容です。

  • モジュール名
  • Go のバージョン

自分で確認したい場合は、ここにファイルがあります:

# folder: ~/go-fodase
cat go.mod

# module github.com/danielhe4rt/gofodase
# 
# go 1.23.2

その後、私が次に気に入ったのは go mod tiny で、これは基本的に不足している依存関係を追加し、未使用の依存関係を削除します。

go mod tidy

この 2 つ目は、これが存在し、本当に便利であることを覚えておいていただくためのものです。おそらくあなたの環境では毎回それを実行することになるので、インポートが消えるのを見るのに慣れるでしょう :p

2.2 CLI: 実行する

プロジェクトを実行する必要があるため、これはおそらく使用する最も一般的なコマンドですが、その仕組みは次のとおりです。

  • main() 関数を含むファイルを指定する必要があります。
  • このファイルはフォルダーのルートにある必要はありません。

このコマンドについて覚えておくべき最も重要なことは、go run コマンドを実行すると、現在のディレクトリで go.mod ファイルが検索され、それがプロジェクト全体 (インポート、パッケージ) のマッピングの基礎として使用されるということです。 、など)。以下にいくつかの例を示します:

# go run <your-main-file>

# Environment 1
# .
# ├── go.mod
# └── main.go
go run app.go

# Environment 2
# .
# ├── go.mod
# └── src
#     └── main.go
go run src/app.go

app.go のコンテンツは次のとおりです:

package main

import(
    "fmt"
)

func main () {
    fmt.Println("whats up! don't forget to like this article <3")
}

これで、プロジェクトを実行するための基本がわかりました。文字通り、ハローワールド!

3. 異なる構文の比較:

Go に関する私の問題は常にその書き方にありましたが、何時間もコーディングを続けた後、思っていたよりも簡単であることがわかりました。ご想像のとおり、私は PHP に精通しており、Rust についてもある程度の経験があります。

2023 年に私が Rust を学び始めたとき、幸運なことに私の大ファンである Nuno Maduro (Laravel) が「Rust 開発者のための PHP」と呼ばれる講演を行ってくれました。構文を理解して、私が完全にRustに踏みにじられていた間、私に一息つけるスペースを与えてくれました。

とにかく、当時は役に立ったので、比較してみませんか?

3.1 構文: クラス/構造体と API のカプセル化

OOP にはクラスがあり、これはコードを小さな部分に抽象化する非常に優れた方法であり、「そのようなもの」が得られます。 Golang は、環境を思いのままに変える壮大な開発となる可能性があるため、

冒険とみなすことができます。

Golang は、「低レベル」実装を簡単に操作できる「システム レベル」構文を提供する「高レベル言語」であることを覚えておいてください。

Go 構文では、次のことができます

    [構造体] 構造体に type を接頭辞として付け、「クラス/構造体」名を追加し、接尾辞として struct を追加して構造体を定義します。
  • [カプセル化]
  • UpperCase または LowerCase の名前で始めることにより、クラス/構造体関連の要素の公開を定義します。
      [可視性: "public"]: 項目名を大文字に設定します。
    • [可視性: "private/protected"]: 項目名を小文字で設定します。
これは、構造体、構​​造体フィールド、構造体メソッドに使用できます。詳しく見てみましょう:


mkdir go-fodase
cd go-fodase

# go mod init <module-name>
go mod init github.com/danielhe4rt/go-fodase
Rust では、より明示的なアプローチ (より oop に近い言語) を使用できます。

    [構造体] 接頭辞 struct を使用して構造体を定義し、「クラス/構造体」名を追加するだけです。
  • [カプセル化] 何かを他の「クレート」に公開したい場合は、公開したいコードの部分に pub プレフィックスを追加する必要があります。
# folder: ~/go-fodase
cat go.mod

# module github.com/danielhe4rt/gofodase
# 
# go 1.23.2
PHP、Java などのように明示的にしたいのですが、立ち止まって考えると、作成する

コードが少なくなりますが、読みやすさにも影響します。

3.2 構文: インターフェイスの実装は FUC として奇妙です*

正直に言うと、私は Go 環境に LARAVEL を入れようとするタイプの人間なのですが、それは Go 環境で既に行われていました。とにかく、私は

「インターフェース/コントラクト駆動開発」 で作業するというアイデアがとても気に入っています。 という言語に初めてこだわりました。

Go では、インターフェイスは構造/クラスに「実装」されません。私のような OOP 担当者にとって、そのような設計上の決定が頭の中に収まるのはまったくクレイジーです。何が期待されるのか見てみましょう:

mkdir go-fodase
cd go-fodase

# go mod init <module-name>
go mod init github.com/danielhe4rt/go-fodase

さて、いよいよ、構造体内に「インターフェース」の明示的な実装がありません。それは、うーん... 奇妙?代わりに、インターフェイスに必要なメソッドを実装するだけで、コンパイル時に go がチェックします。これがコンパイル済み言語であり、決して問題になるはずがないことを知っておくのは当然ですが、私は 開発者エクスペリエンス に関する私の視点について話しています!

# folder: ~/go-fodase
cat go.mod

# module github.com/danielhe4rt/gofodase
# 
# go 1.23.2

いずれにせよ、その言語で時間をかけてコーディングすると、その言語に慣れることができます。ここで、何もダウンロードせずに基本環境が提供するものについて説明しましょう!

4. Stdlib: 間違いなく素晴らしいツールキット

ここでは、サードパーティのパッケージをダウンロードせずに、Go が 標準ライブラリ で提供するすべてについて説明します。以下に時系列のタイムラインを示します:

  • 1日目:何?型がすべてのメソッドを運ぶという点で、なぜ JS/Java が気に入らないのでしょうか? (そして私は両方とも大嫌いです)
  • 第 1 週: 待ってください、多分それは良いことです (プリミティブ型のパッケージを理解した後)
  • 第 2 週: 何?なぜ他の言語にはデフォルトでこのような優れたライブラリがないのでしょうか?

それは冗談ではなく、毎日 Go を探索していると、標準ライブラリの下にクールなライブラリを見つけました。それでは、プリミティブ型について話しましょう。

4.1 パッケージ: プリミティブ型

PHP と同様、また他の多くの言語 (Rust、Java、JS など) とは、Golang は関連する 型操作のほとんどを実行するために "helper" 関数を必要とします。 。彼らには「効用」が付加されていないため、「貧血」タイプと考えることができます。

go mod tidy

"String" 型 を使用している場合は、それを操作するための strconv や string などの他のパッケージがあります。ただし、どのパッケージを確認するかを決して忘れないための黄金律があります。型が文字列の場合は、複数形の名前を持つ同じパッケージを探してください。

簡単に言うと、[]Type と Type に関連する関数が提供されます。

  • 文字列型 -> import ("strings") のような操作: Contains()Upper()Split() ...
  • バイト型 -> Include()Compare()Split() ...
  • などの操作の import ("bytes")
  • など!

自分で検証できるようにコードを見てください:

# go run <your-main-file>

# Environment 1
# .
# ├── go.mod
# └── main.go
go run app.go

# Environment 2
# .
# ├── go.mod
# └── src
#     └── main.go
go run src/app.go

これは簡単なはずですが、頭に入るまでしばらく苦労しました。おそらく、Laravel とそのヘルパー関数を長年使いすぎて、フレームワークなしでコーディングすることがどれほど難しいかを忘れてしまったのかもしれません :D

4.2 パッケージ: 便利なもの

ツールやプロジェクトを調べている間に、多くのプロジェクトについて非常に良い紹介ができたので、それぞれのプロジェクトと使用したライブラリをリストしたいと思います。

  • 独自のシェル チャレンジを作成します:
    • パッケージ:
      • fmt: I/O ライブラリ (画面上のスキャン/読み取りおよび書き込み)
      • os: オペレーション システムと直接通信する関数とヘルパー。
      • strconv: 特定のデータ型を文字列にキャストするか、文字列を定義された任意の型にキャストします。
  • 独自の (HTTP|DNS) サーバーを構築するチャレンジ:
    • パッケージ:
      • net: HTTP、TCP、UDP、Unix ドメイン ソケットなどのネットワーク I/O プロトコルとの統合レイヤー
      • [以前のパッケージ...]
  • 中レベルの宿題の課題はありますか?
    • パッケージ:
      • flag: CLI 引数を変数にキャプチャします
      • log: ログのチャネルをアプリケーションに追加します
      • crypto/rand: 安全な暗号ランダムジェネレーター
      • math/rand: 数学数値ランダムジェネレーター
      • 時間: 期間/時間ライブラリ

ここでは、すべてのパッケージ実装のスクロール可能なビューを確認できるようにしています。ここで引用できるクールな標準パッケージがたくさんあります。

注意: これは大量のコードです。 :p
お気に入りの機能 (ゴルーチンやチャネル以外) についてコメントすることを忘れないでください:p

mkdir go-fodase
cd go-fodase

# go mod init <module-name>
go mod init github.com/danielhe4rt/go-fodase

本当に、それは本当に素晴らしいことです!それでは、テストを続けてみましょう。

5. Go のテストはとても簡単です

Go を使用した 2 番目のプロジェクトでは、Requests と Responses オブジェクトを作成しながらテストを学習する機会がありました。 PHP 環境内では、おそらく PHPUnit や Pest などのサードパーティ ライブラリを使用していると思います。右? Go 環境では、これは 簡単 です!あなたがする必要があるのは次のことだけです:

  • パッケージ内にファイルを作成します: person.go では、テストする関数を記述します。
  • パッケージのテスト ファイルを作成します。** person_test.go というファイルを作成し、独自のテストの作成を開始します。

パッケージフォルダーにrequests.goとrequests_test.goがあるとします。requests.goは次のとおりです。

# folder: ~/go-fodase
cat go.mod

# module github.com/danielhe4rt/gofodase
# 
# go 1.23.2

5.1 テスト: 基本的なテスト

Go のテストは、テスト関数内で (t *Testing.T).Errorf() が呼び出されない場合、合格 (緑色) とみなされます。また、以前に紹介したのと同じカプセル化の概念に従います:

  • 大文字で始まるテスト関数は、テストランナーによって識別されます
  • 小文字で始まるテスト関数は無視されます (通常はヘルパー関数)
mkdir go-fodase
cd go-fodase

# go mod init <module-name>
go mod init github.com/danielhe4rt/go-fodase

独自のヘルパー関数を実行してテストできます。これらのテストではモジュール ドメインに侵入しないように注意してください!

5.2 テスト: Jetbrains ボイラープレート

私は初日から Goland を使用しているので、ほとんどのことが簡単になりました。そのため、新しいテストを開始するたびに、デフォルトで並列実行 (ゴルーチン) される Unity テスト構造を含むこのボイラープレートを取得します。

# folder: ~/go-fodase
cat go.mod

# module github.com/danielhe4rt/gofodase
# 
# go 1.23.2

5.3 テスト: テストの実行

わかりました。Go でテストを作成することが いかに簡単であるかがわかりました。しかし、テストを実行するのはどうでしょうか? 簡単なタスク!必要なのは、パッケージ フォルダーに移動して次を実行することだけです:

go mod tidy

あなたのもののためのいくつかのテストを書き留めてください。必要なものを分離すれば、それほど難しいことではありません:p

6. 循環インポートに注意する

過去数年間の開発中、私は常に「クリーン アーチ」や「ドメイン駆動設計」 にこだわることなく、自分のニーズに合った方法ですべてのプロジェクトをモジュール化するよう努めてきました。 。しかし、パッケージを分割しようとした最初の試みで、「Cyclic Import」 エラーが発生し、次のように考えました。このようなものを見たのはどのくらいぶりですか?

PHP での 2 年間、私はインポート地獄で同じ問題を抱えていました。つまり、特定のフローで 同じファイルを 2 回インポートしないことができませんでした。これは私が PSR-4 (オートローディング) に出会う前のことであり (これにより私の PHP 時代は永遠に変わりました!!)、何年も前の今、私は Go でこれに苦労しています。

循環インポートのシナリオを考えてみましょう:

# go run <your-main-file>

# Environment 1
# .
# ├── go.mod
# └── main.go
go run app.go

# Environment 2
# .
# ├── go.mod
# └── src
#     └── main.go
go run src/app.go

Go で循環インポートにフラグを立てるものをコンパイルしようとすると、次のようなエラーが表示されます。

package main

import(
    "fmt"
)

func main () {
    fmt.Println("whats up! don't forget to like this article <3")
}

そしてこの時点で、それを避けるために依存関係/パッケージの分解を開始する必要があります。

TLDR: 何度もロードされる場所に同じパッケージをインポートしないでください。

7. これも延期、あれも延期…しかし、延期とは何でしょうか?

調べたわけではありませんが、プログラミング言語で予約語 defer を初めて知りました。そして、それは「一般的な予約語」の一部ではなかったので、丸一週間無視しました!

その後、私が言語に数時間苦労しているのを見て、仕事仲間の一人である Dusan が Go のメモリ管理のレッスンをしてくれました。 (はい、これは叫びです:p)

問題は、何かへのバッファ/接続を開いたときは必ずそれを閉じる必要があるということです。 2014 年に MapleStory サーバー (Java) を使用していたとき、最も一般的な問題はメモリ リークであったことを覚えています。これは単に開発者が DB への接続を閉じなかったためです。

これは忘れても大丈夫です!ただし、コードレビューに合格するのはOKではありません(笑)

これは Java の例です:

mkdir go-fodase
cd go-fodase

# go mod init <module-name>
go mod init github.com/danielhe4rt/go-fodase

Golang のコーディング中に、ファイルを開いたらすぐに閉じることを忘れないように、この defer 属性が与えられます。

Defer は「Deference」の略で、コードの特定部分の実行が終了した後にリソースを「クリーン」する方法です。

# folder: ~/go-fodase
cat go.mod

# module github.com/danielhe4rt/gofodase
# 
# go 1.23.2

関数内に多くの遅延を含めることもでき、DEFER ORDER が重要です。 database2 を延期し、次に database1 を延期すると、両方のプロセスが同じ順序でクリーンアップされます。

go mod tidy

これは、プロジェクトでメモリ リークが発生するのを混乱させないための非常に簡単な方法です。何かをストリーミングするときは必ずこれを使用してください。

8.初心者のためのエラー管理

最初のエラー処理は次のようになります: 使用している関数がエラー タイプを返すかどうかを確認し、それを クソ 回ごとに検証します。これが私が話していることの例です:

# go run <your-main-file>

# Environment 1
# .
# ├── go.mod
# └── main.go
go run app.go

# Environment 2
# .
# ├── go.mod
# └── src
#     └── main.go
go run src/app.go

正直に言うと、私はこの構文が大嫌いです。ただし、これは言語の一部であり、コーディングの日々の中で遭遇することになります。

エラーのある関数はエラーまたは (T, エラー) を返すことができますが、幸いなことに Go ではそれを忘れることはありません。

package main

import(
    "fmt"
)

func main () {
    fmt.Println("whats up! don't forget to like this article <3")
}

コードに err != nil をスパム送信すれば、大丈夫です、約束します。 :D

9. 結論の偉業: 低遅延コーディングチャレンジ

環境を理解するために費やしたストレスや時間とは別に、Twitch の視聴者と一緒に新しい言語を学ぶのは素晴らしい挑戦でした。彼らの多くは、長い間私にそれをチェックしてほしいと頼んできたので、ここに来ました。

これらのポイントはすべて、言語に関する私の個人的な開発経験を反映しており、目標は、この 2 週間の言語学習中に私が経験したことを共有することでした。

9.1 おまけ: コーディングチャレンジ

最近、私はチームメイトから ScyllaDB チャレンジを完了するよう挑戦され、並列処理、プール、レート制限について多くのことを学びました。これは、多くの企業が製品のパフォーマンスを向上させるために直面​​する種類の課題です!

このチャレンジの目標は、リクエスト数をレート制限しながらランダム データを ScyllaDB に挿入する小さな Go コマンド ライン アプリケーションを作成することです。

リポジトリ チャレンジは、github.com/basementdevs/throttling-requests-scylla-test で見つけることができます。採用も行っております!求人セクションで募集中のポジションを見つけることができます!

読んでいただきありがとうございます!この記事が Golang の学習について貴重な洞察を提供できれば幸いです。ご意見や経験をお気軽に共有してください。

以上がこれが私が 2 週間で Go について学んだことのすべてです。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。