Go ポインターをいつ使用するか知っていますか?
この記事は、go language チュートリアルコラムで、Go ポインター (Go Pointer) がどのような状況で使用されるのかを紹介するものです。 !
GOコードでのポインターの使用は、特に使用法のシナリオを区別するのが困難な場合、初心者にはそれほど友好的ではありません。
ポインターを使用する際の最大の誤解の 1 つは、Go のポインターが C 言語のポインターに非常に似ているということだと思います。しかし、そうではありません。 Go では、ポインタは C/C と同じように機能しません。
この記事では、Go ポインターを正しく使用する方法について説明します。
間違った結論: ポインターを使用する方が良いでしょうか?
一般に、ポインターを使用すると常に値をコピーする必要がなくなるため、アプリケーションの実行が高速になると考えられています。 Go でも同じ考えがあるのは不思議ではありません。
ただし、Go での ポインターの受け渡しは、通常、値の受け渡し よりも遅くなります。これは、Go がガベージ コレクション言語であることの結果です。関数へのポインタを渡すとき、Go はエスケープ解析を実行して、変数をヒープに格納するかスタックに格納するかを決定する必要があります。これによりすでに余分なオーバーヘッドが追加されていますが、それ以外の場合は変数をヒープに保存できます。変数をヒープに保存すると、GC の実行中に時間もロスします。
Go の便利な機能は、コマンド go build -gcflags="-m"
を実行することで、エスケープ解析がどのように行われたかを確認できることです。これを行うと、Go は変数がヒープにエスケープするかどうかを教えてくれます:
./main.go:44:20: greet ... argument does not escape ./main.go:44:21: greeting escapes to heap ./main.go:44:21: name escapes to heap
変数がヒープにエスケープしない場合、変数はスタック上に残ります。スタックは変数をクリアするためにガベージ コレクターを必要とせず、push/pop
操作のみを実行します。
コンテンツが値によって渡される場合、そのコンテンツは常にスタック上で処理されるため、ガベージ コレクションのオーバーヘッドは発生しません。 (GC はデフォルトで実行されます。ヒープ内のコンテンツが少ないということは、GC が行うべき作業が少ないことを意味します)。
ポインターを使用するとパフォーマンスが低下することがわかりました。必要な場合はポインターを使用しますか?
大規模なデータ構造のコピーポインタのパフォーマンスは常に値の転送より悪いのでしょうか?明らかにそうではありません。大規模なデータ構造を扱う場合、ポインタが役に立ちます。これにより、ガベージ コレクションのコストが大量のデータのコピーのコストで相殺される可能性があります。 これについて話すと、「そのビッグデータはどのくらいの大きさにすべきですか?」といつも尋ねられます。 ここに固定値はないと思いますが、パフォーマンスに関連するものはすべてベンチマークする必要があります。 Go には強力なベンチマーク ツールが組み込まれており、これを最大限に活用できます。変数関数のパラメーターを変更する唯一の方法は、ポインターを渡すことです。デフォルトでは、値の変更はコピーに対して実行されます。したがって、これらの変更は、それを呼び出す関数に反映できません。 次のコードを見てください:type person struct { name string }func main() { p := person{"Richard"} rename(p) fmt.Println(p) }func rename(p person) { p.name = "test" }
Richard になります。基になる人物オブジェクトの値を変更する場合は、ポインターを使用する必要があります。
func main() { p := person{"Richard"} rename(&p) fmt.Println(p) }func rename(p *person) { p.name = "test" }
testを出力します。可変性とは、Go でポインターが使用される状況です。これが良いことなのかどうかは議論の余地がある。
func (p *person) rename(s string) { p.name = s }func (p *person) printName() { fmt.Println(p.name) }
func (p *person) rename(s string) { p.name = s }func (p person) printName() { fmt.Println(p.name) }
printName でポインターを使用する必要はありません。ただし、これにより API が簡素化され、参照が必要な場所を正確に覚えておく必要がなくなります。
nil ポインターであり、値が設定されていないことを意味します。この要件は、次のように実装することもできます。
type exam struct { score int present bool }
present フィールドを使用して、学生が試験を受けなかったことを示します。
Go では可能な限りデフォルト値を使用することが合理的であると考えています。これはすべての状況で機能するわけではありませんが、私の場合は大きな事故を防ぐことができました。ポインターの代わりに値を使用すると、NULL ポインターによるトニー・ホアの「100 万ドルの間違い」は発生しません。
デフォルト値のゼロは、多数の宣言を避けるのに役立ちます。
另一个好处是易变性造成的问题比它解决的问题多的得多。易变性给函数带来的副作用同时使得调试变得更加困难。 通过让函数返回修改之后的结构体,可以避免这种突变。
重写之前的例子
func main() { p := person{"richard"} p = rename(p) fmt.Println(p) }func rename(p person) person { p.name = "test" return p }
这也是 append
如何工作的,所以并不陌生。
x := []int{1,2} x = append(x, 3) x = append(x, 4)
鉴于指针的安全性,和值处理比指针处理更快,使用指针需要反复斟酌。
原文地址:https://medium.com/@meeusdylan/when-to-use-pointers-in-go-44c15fe04eac
译文地址:https://learnku.com/go/t/60923
以上がGo ポインターをいつ使用するか知っていますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











Go では、gorilla/websocket パッケージを使用して WebSocket メッセージを送信できます。具体的な手順: WebSocket 接続を確立します。テキスト メッセージを送信します。 WriteMessage(websocket.TextMessage,[]byte("message")) を呼び出します。バイナリ メッセージを送信します。WriteMessage(websocket.BinaryMessage,[]byte{1,2,3}) を呼び出します。

メモリ リークは、ファイル、ネットワーク接続、データベース接続などの使用されなくなったリソースを閉じることによって、Go プログラムのメモリを継続的に増加させる可能性があります。弱参照を使用してメモリ リークを防ぎ、強参照されなくなったオブジェクトをガベージ コレクションの対象にします。 go coroutine を使用すると、メモリ リークを避けるために、終了時にコルーチンのスタック メモリが自動的に解放されます。

Go では、正規表現を使用してタイムスタンプを照合できます。ISO8601 タイムスタンプの照合に使用されるような正規表現文字列をコンパイルします。 ^\d{4}-\d{2}-\d{2}T \d{ 2}:\d{2}:\d{2}(\.\d+)?(Z|[+-][0-9]{2}:[0-9]{2})$ 。 regexp.MatchString 関数を使用して、文字列が正規表現と一致するかどうかを確認します。

Go と Go 言語は、異なる特性を持つ別個の存在です。 Go (Golang とも呼ばれます) は、同時実行性、高速なコンパイル速度、メモリ管理、およびクロスプラットフォームの利点で知られています。 Go 言語の欠点としては、他の言語に比べてエコシステムが充実していないこと、構文が厳格であること、動的型付けが欠如していることが挙げられます。

ポインターと参照を使用すると、C++ でのメモリ使用量を最適化できます。 ポインター: 他の変数のアドレスを格納し、別の変数を指すことができるため、メモリが節約されますが、ワイルド ポインターが生成される可能性があります。参考: 別の変数にエイリアスされ、常に同じ変数を指し、ワイルド ポインターを生成せず、関数パラメーターに適しています。メモリ使用量を最適化すると、不必要なコピーを回避し、メモリ割り当てを削減し、スペースを節約することにより、コードの効率とパフォーマンスを向上させることができます。

並行関数の単体テストは、同時環境での正しい動作を確認するのに役立つため、非常に重要です。同時実行機能をテストするときは、相互排他、同期、分離などの基本原則を考慮する必要があります。並行機能は、シミュレーション、競合状態のテスト、および結果の検証によって単体テストできます。

明確で包括的なドキュメントを作成することは、Golang フレームワークにとって非常に重要です。ベスト プラクティスには、Google の Go コーディング スタイル ガイドなど、確立されたドキュメント スタイルに従うことが含まれます。見出し、小見出し、リストなどの明確な組織構造を使用し、ナビゲーションを提供します。スタート ガイド、API リファレンス、概念など、包括的で正確な情報を提供します。コード例を使用して、概念と使用法を説明します。ドキュメントを常に最新の状態に保ち、変更を追跡し、新機能を文書化します。 GitHub の問題やフォーラムなどのサポートとコミュニティ リソースを提供します。 API ドキュメントなどの実践的なサンプルを作成します。

GoWebSocket をデータベースと統合する方法: データベース接続をセットアップする: データベースに接続するには、database/sql パッケージを使用します。 WebSocket メッセージをデータベースに保存する: INSERT ステートメントを使用して、メッセージをデータベースに挿入します。データベースから WebSocket メッセージを取得する: データベースからメッセージを取得するには、SELECT ステートメントを使用します。
