[インデックス 1588] ファイルの概要
このコミットは、Go言語のチュートリアルに含まれるサーバーコードのクリーンアップを目的としています。具体的には、チュートリアル内のサンプルコードにおける型名の命名規則をGo言語の慣習に合わせる変更が行われています。これにより、コードの可読性とGo言語のイディオムへの準拠が向上しています。
コミット
commit 96777ea2a756bcb0f31946e4f1bfa375d5505830
Author: Rob Pike <r@golang.org>
Date: Fri Jan 30 10:18:58 2009 -0800
clean up server code in tutorial
R=rsc
DELTA=15 (1 added, 0 deleted, 14 changed)
OCL=23889
CL=23889
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/96777ea2a756bcb0f31946e4f1bfa375d5505830
元コミット内容
clean up server code in tutorial
R=rsc
DELTA=15 (1 added, 0 deleted, 14 changed)
OCL=23889
CL=23889
変更の背景
このコミットの主な背景は、Go言語のチュートリアルコードの品質と一貫性を向上させることです。特に、Go言語では識別子(変数、関数、型など)の最初の文字が大文字か小文字かによって、その識別子がエクスポートされる(パッケージ外からアクセス可能になる)か、アンエクスポートされる(パッケージ内でのみアクセス可能になる)かが決まるという重要な命名規則があります。
元のコードでは、Request
という型名が大文字で始まっていましたが、これは通常、パッケージ外に公開されるべき型に用いられる命名です。しかし、チュートリアル内のこのRequest
型は、そのコンテキストにおいてパッケージ内部でのみ使用されることを意図している可能性が高いです。同様に、BinOp
も同様の理由で変更されています。
このコミットは、Go言語のイディオムと命名規則に沿って、内部的に使用される型名を小文字で始めるrequest
およびbinOp
に変更することで、コードの意図をより明確にし、Go言語のベストプラクティスに準拠させることを目的としています。これにより、チュートリアルを読む学習者がGo言語の正しい命名規則を理解しやすくなります。
また、doc/progs/run
ファイルにおけるserver
の実行に関するコメント変更も行われています。以前は「server hangs; don't run it」とありましたが、変更後は「server hangs; don't run it, just compile it」となり、さらに6g server.go
というコンパイルコマンドが追加されています。これは、チュートリアルのサーバーコードが完全な実行可能なアプリケーションとして設計されているわけではなく、概念を説明するためのものであるため、実行ではなくコンパイルのみを推奨する意図があると考えられます。
前提知識の解説
Go言語の命名規則(エクスポートとアンエクスポート)
Go言語には、識別子(変数、関数、型、定数など)の可視性を制御するための独特かつシンプルな命名規則があります。
- エクスポートされた識別子 (Exported Identifiers): 識別子の名前が大文字で始まる場合、その識別子はパッケージ外からアクセス可能です。これは、他のパッケージから利用できるAPIの一部として公開されることを意味します。例えば、
MyStruct
、DoSomething
など。 - アンエクスポートされた識別子 (Unexported Identifiers): 識別子の名前が小文字で始まる場合、その識別子は定義されたパッケージ内でのみアクセス可能です。これは、パッケージの内部実装の詳細であり、外部からは直接利用できないことを意味します。例えば、
myField
、calculateInternal
など。
この規則は、Go言語におけるモジュール性(カプセル化)の基本的なメカニズムであり、APIの設計において非常に重要です。外部に公開すべきでない内部的な型や関数は小文字で始めることで、意図しない外部からのアクセスを防ぎ、パッケージのインターフェースを明確に保ちます。
Go言語の並行処理(GoroutineとChannel)
このコミットで変更されているコードは、Go言語の並行処理の主要な概念であるgoroutine
とchannel
を使用しています。
- Goroutine: Go言語における軽量なスレッドのようなものです。
go
キーワードを関数呼び出しの前に置くことで、その関数を新しいgoroutineとして並行して実行できます。非常に低コストで生成でき、数千、数万のgoroutineを同時に実行することが可能です。 - Channel: goroutine間でデータを安全にやり取りするための通信メカニズムです。チャネルは、goroutine間の同期と通信を可能にし、共有メモリによる競合状態(race condition)を防ぐのに役立ちます。チャネルは型付けされており、特定の型の値のみを送受信できます。
チュートリアルのサーバーコードは、goroutine
を使ってリクエスト処理を並行化し、channel
を使ってリクエストとレスポンスをやり取りするパターンを示しています。
技術的詳細
このコミットの技術的な変更は、主にGo言語の命名規則への準拠と、それに伴うコードの整合性の維持にあります。
-
型名の変更:
Request
型がrequest
型にリネームされました。BinOp
型がbinOp
型にリネームされました。 この変更は、これらの型がパッケージ内部でのみ使用されることを意図しているため、Go言語の命名規則に従い、アンエクスポートされた(小文字で始まる)名前に変更されたものです。
-
変数名の変更:
request
型のインスタンスを参照する変数名が、request
からreq
に変更されました。これは、型名と変数名が同じになることを避けるための一般的なGoの慣習です。req
はrequest
の短縮形としてよく使われます。
-
関数シグネチャの変更:
run
、server
、startServer
といった関数が、引数や戻り値の型として*Request
や*BinOp
を使用していた箇所が、それぞれ*request
や*binOp
に変更されました。これは、型名のリネームに伴う必然的な変更であり、コード全体の整合性を保つために必要です。
-
チュートリアルテキストの修正:
doc/go_tutorial.txt
内の説明文で、"Request" type
という記述が"request" type
に修正されました。これは、コードの変更に合わせてチュートリアルの説明も更新されたことを示しています。
-
doc/progs/run
の変更:server
プログラムの実行に関するコメントが変更され、コンパイルのみを推奨するようになりました。6g server.go
というコンパイルコマンドが追加されました。6g
はGoの初期のコンパイラ名であり、当時のGo環境におけるコンパイル方法を示しています。
これらの変更は、機能的な振る舞いを変更するものではなく、コードのスタイルとGo言語のイディオムへの準拠を改善するためのものです。これにより、チュートリアルコードがより「Goらしい」ものとなり、学習者にとっての模範となることを意図しています。
コアとなるコードの変更箇所
doc/go_tutorial.txt
--- a/doc/go_tutorial.txt
+++ b/doc/go_tutorial.txt
@@ -755,7 +755,7 @@ With channels, it's possible to serve multiple independent client goroutines wit
writing an actual multiplexer. The trick is to send the server a channel in the message,
which it will then use to reply to the original sender.
A realistic client-server program is a lot of code, so here is a very simple substitute
-to illustrate the idea. It starts by defining a "Request" type, which embeds a channel
+to illustrate the idea. It starts by defining a "request" type, which embeds a channel
that will be used for the reply.
--PROG progs/server.go /type.request/ /^}/
doc/progs/run
--- a/doc/progs/run
+++ b/doc/progs/run
@@ -68,7 +68,8 @@ testit print_string "" "77 Sunset Strip"
testitpipe sieve "sed 10q" "2 3 5 7 11 13 17 19 23 29"
testitpipe sieve "sed 10q" "2 3 5 7 11 13 17 19 23 29"
-# server hangs; don't run it
+# server hangs; don't run it, just compile it
+6g server.go
testit server1 "" ""
rm -f 6.out *.6
doc/progs/server.go
--- a/doc/progs/server.go
+++ b/doc/progs/server.go
@@ -11,21 +11,21 @@ type request struct {
type binOp (a, b int) int;
-func run(op *BinOp, request *Request) {
- result := op(request.a, request.b);
- request.replyc <- result;
+func run(op *binOp, req *request) {
+ result := op(req.a, req.b);
+ req.replyc <- result;
}
-func server(op *BinOp, service chan *Request) {
+func server(op *binOp, service chan *request) {
for {
- request := <-service;
- go run(op, request); // don't wait for it
+ req := <-service;
+ go run(op, req); // don't wait for it
}
}
-func startServer(op *BinOp) chan *Request {
- req := make(chan *Request);
- go Server(op, req);
+func startServer(op *binOp) chan *request {
+ req := make(chan *request);
+ go server(op, req);
return req;
}
doc/progs/server1.go
--- a/doc/progs/server1.go
+++ b/doc/progs/server1.go
@@ -11,9 +11,9 @@ type request struct {
type binOp (a, b int) int;
-func run(op *binOp, request *request) {
- result := op(request.a, request.b);
- request.replyc <- result;
+func run(op *binOp, req *request) {
+ result := op(req.a, req.b);
+ req.replyc <- result;
}
func server(op *binOp, service chan *request, quit chan bool) {
コアとなるコードの解説
このコミットで変更されたGoコードは、Go言語の並行処理モデル(goroutineとchannel)を用いたシンプルなサーバーの例です。
-
type request struct { ... }
:- これはクライアントからのリクエストを表す構造体です。
a
とb
は演算のオペランド、replyc
はサーバーが結果をクライアントに送り返すためのチャネルです。 - 元のコードでは
Request
と大文字で始まっていましたが、このコミットでrequest
と小文字に変更されました。これにより、この型がパッケージ内部でのみ使用されることを明確に示しています。
- これはクライアントからのリクエストを表す構造体です。
-
type binOp (a, b int) int;
:- これは二項演算を表す関数型です。
a
とb
という2つの整数を引数にとり、整数を返します。 - 元のコードでは
BinOp
と大文字で始まっていましたが、このコミットでbinOp
と小文字に変更されました。これもrequest
型と同様に、内部使用を意図した変更です。
- これは二項演算を表す関数型です。
-
func run(op *binOp, req *request)
:- この関数は、与えられた二項演算
op
をリクエストreq
のオペランドa
とb
に適用し、その結果をリクエストのreplyc
チャネルに送信します。 - 引数の型が
*BinOp
から*binOp
に、*Request
から*request
に変更され、変数名もrequest
からreq
に変更されました。
- この関数は、与えられた二項演算
-
func server(op *binOp, service chan *request)
:- この関数はサーバーのメインループです。
service
チャネルからリクエストを受け取り、新しいgoroutineでrun
関数を呼び出してリクエストを処理します。go run(op, req)
とすることで、各リクエストが並行して処理され、サーバーが次のリクエストをすぐに受け付けられるようになります。 - 引数の型が
*BinOp
から*binOp
に、chan *Request
からchan *request
に変更され、変数名もrequest
からreq
に変更されました。
- この関数はサーバーのメインループです。
-
func startServer(op *binOp) chan *request
:- この関数はサーバーを起動し、クライアントがリクエストを送信するためのチャネルを返します。新しいgoroutineで
server
関数を起動します。 - 引数の型が
*BinOp
から*binOp
に、戻り値の型がchan *Request
からchan *request
に変更されました。また、go Server(op, req)
がgo server(op, req)
に変更され、関数名の先頭が大文字から小文字に修正されています。これは、server
関数自体もパッケージ内部でのみ使用されることを意図しているため、Goの命名規則に合わせた変更です。
- この関数はサーバーを起動し、クライアントがリクエストを送信するためのチャネルを返します。新しいgoroutineで
これらの変更は、Go言語の命名規則に厳密に従うことで、コードの意図(内部使用か外部公開か)を明確にし、Go言語のイディオムに沿ったコードスタイルを維持することを目的としています。
関連リンク
特になし。
参考にした情報源リンク
- https://github.com/golang/go/commit/96777ea2a756bcb0f31946e4f1bfa375d5505830
- Go言語の命名規則(エクスポートとアンエクスポート)に関するWeb検索結果:
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQE2lv9uzEhudiUFh8q-GtWWpVKAyBFWTbiiWRo9dC9GEM6-AfrgDI5hgp9BoZyDQuM8Yamfkgw3sVqPeNRL-FEKlY6F6rMdqk4nJTAvmrUw9OjrVKxwOP6y7qbYp5RpGyaNNr7ApCBiw13Dh27Vb1wjGGtHWXaJRa1RwHAfdZSwfzTrTv5U
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFybthRhNIzeYHv2CrhW4YJZPNkuZrXeHY4PKDZRnUtV2eA4ocAhxnkmt7MWx0MBhl2oJ9NkXsW1rE2rRfpVHkAeCLBP2n65c5iPXRcTO1qryvoColvrEJUKpvP2_3S6vjCm1h23jnm4ggXlebLJ1jrNeoKmC5Uw4H8e9jZZ409SbOZGuCyD8xkjVTb_f2DCPT1P1zIm0vgbmCqkkTHBtVUXJnmrlfpqG2foe0w5mYzzqiftnOI7v0=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQH6tgN8Ho-zDZyVTbjF4Jtjp9NWim0kQb3eh7aIBFxopLLKDAmZTyRIZnI2DR6dB9zGV98JbHmnNkSJ7C0kTsPFzedLl7sOx-dVoKmvcqvJilhLPiqeAL8rJPeWCbcbwp7NCi4wu9f-Rv-Q2STEAtt-k765RwxIZvIV3-m-Mzn1qhp1oVntAteVhzuf
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHVzC4pK2HaxTQCN5SXru5ERetKaBfRRLBavWo1dNQjsaPx27zpgPVQQWBRpgzKS362GdJm-kBLQbuwrzbFrTCK5T9bEp-Hncb0yMufc0DySugXvCDobTh-DT22hBLRT2ZE4qWwVJvLnFk1GFBqU6uuYkAFATvsgLx22uVAcCjDVG6j9kK6qpm3h84Q_h-hyFGdxI4d-yAJ7dXjrE==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEmfKdC2tlbUm00RlM1u9JycWoXybCDQdQMrSbPOcfMY03Vs_mIn2JW6Sv2miDqfnU69xoi2a9MKITCuAvESd8OENwEJbolClI6hSJtGafJ1FMrosLiLzpK5zae0sIC65mE0bIxEQZZFyzZWgloHqJQ