[インデックス 1530] ファイルの概要
このコミットは、Go言語のチュートリアルドキュメント doc/go_tutorial.txt
と、それに付随するサンプルプログラム doc/progs/cat_rot13.go
, doc/progs/server.go
, doc/progs/sieve.go
を更新するものです。主な目的は、Go言語の新しいエクスポート(公開)スキームに合わせて、チュートリアルの内容とコード例を修正することです。具体的には、識別子の可視性に関するGoの規則(大文字で始まる識別子はエクスポートされ、小文字で始まる識別子はパッケージ内部に限定される)を反映させるための変更が中心となっています。
コミット
commit ae05f00b46bee5e1ec1cc56822badebd4576f610
Author: Rob Pike <r@golang.org>
Date: Tue Jan 20 19:32:36 2009 -0800
update tutorial for new export scheme
R=ken,rsc
DELTA=101 (9 added, 0 deleted, 92 changed)
OCL=23174
CL=23188
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/ae05f00b46bee5e1ec1cc56822badebd4576f610
元コミット内容
update tutorial for new export scheme
R=ken,rsc
DELTA=101 (9 added, 0 deleted, 92 changed)
OCL=23174
CL=23188
変更の背景
このコミットが行われた2009年1月は、Go言語がまだ開発の初期段階にあり、言語仕様が活発に進化していた時期です。Go言語の設計思想の一つに「シンプルさ」と「明瞭さ」があります。その一環として、他の多くの言語で見られる public
, private
, protected
といった明示的なアクセス修飾子を廃し、識別子の命名規則によって可視性を制御する「エクスポートスキーム」が導入されました。
このコミットの背景には、Go言語がこの新しいエクスポートスキーム(大文字で始まる識別子はエクスポートされ、小文字で始まる識別子はパッケージ内部に限定される)を採用したことがあります。チュートリアルは言語の基本的な使い方を教えるものであるため、この重要な変更を反映させる必要がありました。特に、以前のバージョンでは export
キーワードが存在していた可能性があり、それが廃止され、大文字・小文字の区別による可視性制御に移行したことをチュートリアルで明確に伝える必要がありました。
前提知識の解説
Go言語の識別子の可視性(エクスポートスキーム)
Go言語では、パッケージ内の識別子(変数、関数、型、メソッド、構造体フィールドなど)の可視性は、その識別子の名前の最初の文字が大文字か小文字かによって決まります。
- エクスポートされた識別子 (Exported Identifiers): 識別子の名前が大文字で始まる場合、その識別子はエクスポートされます。これは、その識別子が定義されているパッケージをインポートする他のパッケージからアクセス可能であることを意味します。例えば、
fmt.Printf
のPrintf
は大文字で始まるため、fmt
パッケージの外部から呼び出すことができます。 - エクスポートされない識別子 (Unexported Identifiers): 識別子の名前が小文字で始まる場合、その識別子はエクスポートされません。これは、その識別子が定義されているパッケージの内部からのみアクセス可能であることを意味します。他のパッケージからは直接アクセスできません。例えば、
internal
パッケージ内の関数や変数は、通常小文字で始まり、そのパッケージ内でのみ使用されます。
この規則は、Go言語の設計哲学である「明示的なものは少なく、暗黙的なものは多く」を体現しており、コードの簡潔さを保ちつつ、モジュール性を高めるのに役立っています。
sys
パッケージ
Go言語の初期には、sys
パッケージというものが存在し、システムコールやコマンドライン引数へのアクセスなど、基本的なシステム関連の機能を提供していました。このコミットでは、sys.exit(1)
が sys.Exit(1)
に、sys.argc()
や sys.argv(int)
が sys.Args
に変更されています。これは、sys
パッケージ内の識別子も新しいエクスポートスキームに従って大文字化されたことを示唆しています。後のGoのバージョンでは、これらの機能は os
パッケージなどに再編成され、sys
パッケージは廃止されています。
fmt
パッケージ
fmt
パッケージは、Go言語におけるフォーマットされたI/O(入出力)を提供する標準ライブラリです。C言語の printf
に似た機能を提供し、文字列のフォーマット、標準出力への出力、ファイルへの書き込みなどを行います。このコミットでは、printf
が Printf
に、print
が Print
に、println
が Println
に、sprint
が Sprint
に、fprintf
が Fprintf
に変更されています。これらもまた、新しいエクスポートスキームに従って、パッケージ外部から利用可能な関数名が大文字化されたことを示しています。
インターフェース
Go言語のインターフェースは、メソッドのシグネチャの集合を定義する型です。ある型がインターフェースで定義されたすべてのメソッドを実装していれば、その型はそのインターフェースを「実装している」とみなされます。このコミットでは、チュートリアル内の Reader
インターフェースが reader
に、Writer
インターフェースが writer
に変更されています。これは、インターフェース名も可視性規則に従うことを示しており、この場合はパッケージ内部でのみ使用されることを意図している可能性があります。
ゴルーチンとチャネル
Go言語の並行処理の根幹をなすのがゴルーチン(軽量スレッド)とチャネル(ゴルーチン間の通信手段)です。チュートリアルでは、素数篩(ふるい)の例やクライアント・サーバーの例でゴルーチンとチャネルが使われています。このコミットでは、Generate
関数が generate
に、Filter
関数が filter
に、Server
関数が server
に、StartServer
関数が startServer
に変更されています。これらの変更も、関数名がパッケージ内部でのみ使用されることを意図して小文字化されたことを示しています。
技術的詳細
このコミットの技術的詳細は、主にGo言語のチュートリアルドキュメント doc/go_tutorial.txt
の内容が、新しいエクスポートスキームに合わせて修正された点に集約されます。
-
エクスポートキーワードの削除と可視性規則の明記:
- 以前のチュートリアルでは、構造体のフィールドをエクスポートするために
export
キーワードが使われていた可能性があります(The "export" keyword makes the declared structure visible to users of the package.
)。このコミットでは、この記述が削除され、代わりに「大文字で始まる識別子はパッケージ外部から見える(エクスポートされる)」というGoの可視性規則が明確に説明されています。 Because "FD" starts with a capital letter, the type is available outside the package, that is, by users of the package. In Go the rule about visibility of information is simple: if a name (of a top-level type, function, method, constant, variable, or of a structure field) is capitalized, users of the package may see it. Otherwise, the name and hence the thing being named is visible only inside the package in which it is declared. In Go, the term for publicly visible names is ''exported''.
- これにより、Go言語の可視性制御がキーワードではなく命名規則に依存するという、その後のGoの標準となる設計がチュートリアルで明示されました。
- 以前のチュートリアルでは、構造体のフィールドをエクスポートするために
-
識別子の大文字・小文字の変更:
- チュートリアル内のコード例や説明文で参照される関数名、型名、インターフェース名などが、その可視性に応じて大文字または小文字に変更されています。
sys.exit(1)
->sys.Exit(1)
:Exit
関数がエクスポートされるようになったことを示します。sys.argc()
とsys.argv(int)
->sys.Args
: コマンドライン引数へのアクセス方法が、関数呼び出しからArgs
というエクスポートされた変数(配列)に変わったことを示します。NewFD
->newFD
:NewFD
関数がパッケージ内部でのみ使用されることを意図して小文字化されました。printf
->Printf
,print
->Print
,println
->Println
,sprint
->Sprint
,fprintf
->Fprintf
:fmt
パッケージの主要なI/O関数がエクスポートされるようになったことを示します。Reader
->reader
,Rot13
->rotate13
: インターフェース名や型名が小文字化され、パッケージ内部での使用が意図されていることを示します。Generate
->generate
,Filter
->filter
,Sieve
->sieve
: 素数篩の例で使われる関数名が小文字化され、パッケージ内部での使用が意図されていることを示します。Request
->request
,BinOp
->binOp
,Server
->server
,StartServer
->startServer
: クライアント・サーバーの例で使われる型名や関数名が小文字化され、パッケージ内部での使用が意図されていることを示します。
-
コード例の更新:
doc/progs/cat_rot13.go
,doc/progs/server.go
,doc/progs/sieve.go
内のコードも、チュートリアルの説明に合わせて識別子の命名が変更されています。例えば、server.go
ではRequest
型がrequest
に、BinOp
型がbinOp
に、Server
関数がserver
に、StartServer
関数がstartServer
に変更されています。
これらの変更は、Go言語の初期段階における言語仕様の成熟と、その設計思想がチュートリアルという形でユーザーに伝えられる過程を示しています。
コアとなるコードの変更箇所
このコミットのコアとなる変更は、主に doc/go_tutorial.txt
内のテキストと、それに合わせて更新されたサンプルコードの識別子の命名規則の変更です。
doc/go_tutorial.txt
の変更
sys.exit(1)
からsys.Exit(1)
へ:- sys.exit(1) + sys.Exit(1)
sys.argc()
とsys.argv(int)
からsys.Args
へ:-started; for instance, "sys.argc()" and "sys.argv(int)" are used by the -"flag" package to access the arguments. +started; for instance, "sys.Args" is an array used by the +"flag" package to access the command-line arguments.
export
キーワードの説明の削除と可視性規則の追加:-that the file descriptor refers to. The "export" keyword makes the declared -structure visible to users of the package. +that the file descriptor refers to. +Because "FD" starts with a capital letter, the type is available outside the package, +that is, by users of the package. In Go the rule about visibility of information is +simple: if a name (of a top-level type, function, method, constant, variable, or of +a structure field) is capitalized, users of the package may see it. Otherwise, the +name and hence the thing being named is visible only inside the package in which +it is declared. In Go, the term for publicly visible names is ''exported''.
NewFD
からnewFD
へ:---PROG progs/fd.go /NewFD/ /^}/\ +++PROG progs/fd.go /newFD/ /^}/\
-The "NewFD" function was not exported because it's internal. The proper factory -to use is "Open": +The "newFD" function was not exported because it's internal. The proper, +exported factory to use is "Open":
syscall.open
からsyscall.Open
へ:-"syscall.open" +"syscall.Open"
- インターフェース名
Reader
からreader
へ:---PROG progs/cat_rot13.go /type.Reader/ /^}/\ +++PROG progs/cat_rot13.go /type.reader/ /^}/\
-Any type that implements the two methods of "Reader" -- regardless of whatever +Any type that implements the two methods of "reader" -- regardless of whatever
- 型名
Rot13
からrotate13
へ:---PROG progs/cat_rot13.go /type.Rot13/ /end.of.Rot13/\ +++PROG progs/cat_rot13.go /type.rotate13/ /end.of.rotate13/\
printf
からPrintf
、print
からPrint
、println
からPrintln
、sprint
からSprint
、fprintf
からFprintf
へ:-There's a package "fmt" that implements a version of "printf" that should -look familiar: +There's a package "fmt" that implements a version of "Printf" (upper case) +that should look familiar:
-Within the "fmt" package, "printf" is declared with this signature: +Within the "fmt" package, "Printf" is declared with this signature:
-reflection helps explain some of the nice properties of Go's printf, -due to the ability of "printf" to discover the type of its arguments +reflection helps explain some of the nice properties of Go's Printf, +due to the ability of "Printf" to discover the type of its arguments
-can just say "%d"; "printf" knows the size and signedness of the +can just say "%d"; "Printf" knows the size and signedness of the
-You can drop the formatting altogether if you use "print" or "println" -instead of "printf". Those routines do fully automatic formatting. -The "print" function just prints its elements out using the equivalent -of "%v" while "println" automatically inserts spaces between arguments +You can drop the formatting altogether if you use "Print" or "Println" +instead of "Printf". Those routines do fully automatic formatting. +The "Print" function just prints its elements out using the equivalent +of "%v" while "Println" automatically inserts spaces between arguments
-If you have your own type you'd like "printf" or "print" to format, +If you have your own type you'd like "Printf" or "Print" to format,
-Observe that the "String()" method calls "sprint" (the obvious Go -variant) to do its formatting; special formatters can use the "fmt" -library recursively. +Observe that the "String()" method calls "Sprint" (the obvious Go +variant that returns a string) to do its formatting; special formatters +can use the "fmt" library recursively.
-Another feature of "printf" is that the format "%T" will print a string +Another feature of "Printf" is that the format "%T" will print a string
-You might ask, though, how "printf" can tell whether a type implements +You might ask, though, how "Printf" can tell whether a type implements
-One last wrinkle. To complete the suite, besides "printf" etc. and "sprintf" -etc., there are also "fprintf" etc. Unlike in C, "fprintf"'s first argument is +One last wrinkle. To complete the suite, besides "Printf" etc. and "Sprintf" +etc., there are also "Fprintf" etc. Unlike in C, "Fprintf"'s first argument is
-Thus you can call "fprintf" on any type that implements a standard "Write()" +Thus you can call "Fprintf" on any type that implements a standard "Write()"
- 関数名
Generate
からgenerate
、Filter
からfilter
、Sieve
からsieve
へ:-The function "Generate" sends the sequence 2, 3, 4, 5, ... to its +The "generate" function sends the sequence 2, 3, 4, 5, ... to its
-The "Filter" function has three arguments: an input channel, an output +The "filter" function has three arguments: an input channel, an output
-Line 23 creates the initial channel to pass to "Generate", which it -then starts up. As each prime pops out of the channel, a new "Filter" +Line 23 creates the initial channel to pass to "generate", which it +then starts up. As each prime pops out of the channel, a new "filter"
-of "Generate", from "progs/sieve1.go": +of "generate", from "progs/sieve1.go":
---PROG progs/sieve1.go /func.Generate/ /^}/\ +++PROG progs/sieve1.go /func.generate/ /^}/\
-The "Sieve" function's main loop becomes simpler and clearer as a +The "sieve" function's main loop becomes simpler and clearer as a
---PROG progs/sieve1.go /func.Sieve/ /^}/\ +++PROG progs/sieve1.go /func.sieve/ /^}/\
- 型名
Request
からrequest
、BinOp
からbinOp
、関数名Server
からserver
、StartServer
からstartServer
へ:---PROG progs/server.go /type.Request/ /^}/\ +++PROG progs/server.go /type.request/ /^}/\
---PROG progs/server.go /type.BinOp/ /^}/\ +++PROG progs/server.go /type.binOp/ /^}/\
-Line 8 defines the name "BinOp" to be a function taking two integers and +Line 8 defines the name "binOp" to be a function taking two integers and
-The "Server" routine loops forever, receiving requests and, to avoid blocking due to +The "server" routine loops forever, receiving requests and, to avoid blocking due to
---PROG progs/server.go /func.Server/ /^}/\ +++PROG progs/server.go /func.server/ /^}/\
---PROG progs/server.go /func.StartServer/ /^}/\ +++PROG progs/server.go /func.startServer/ /^}/\
doc/progs/cat_rot13.go
の変更
- コメントの変更:
-// end of Rotate13 implementation +// end of rotate13 implementation
doc/progs/server.go
の変更
- 型名
Request
からrequest
へ:-type Request struct { +type request struct {
- 型名
BinOp
からbinOp
へ:-type BinOp (a, b int) int; +type binOp (a, b int) int;
- 関数名
Run
からrun
へ:-func Run(op *BinOp, request *Request) { +func run(op *BinOp, request *Request) {
- 関数名
Server
からserver
へ:-func Server(op *BinOp, service chan *Request) { +func server(op *BinOp, service chan *Request) {
- 関数名
StartServer
からstartServer
へ:-func StartServer(op *BinOp) chan *Request { +func startServer(op *BinOp) chan *Request {
main
関数内の呼び出しと変数宣言の変更:- adder := StartServer(func(a, b int) int { return a + b }); + adder := startServer(func(a, b int) int { return a + b }); const N = 100; - var reqs [N]Request; + var reqs [N]request;
doc/progs/sieve.go
の変更
- コメントの変更:
-// The prime sieve: Daisy-chain Filter processes together. +// The prime sieve: Daisy-chain filter processes together.
generate
関数の呼び出しの変更:- go generate(ch); // Start Generate() as a goroutine. + go generate(ch); // Start generate() as a goroutine.
コアとなるコードの解説
これらの変更は、Go言語の「エクスポートスキーム」という、識別子の可視性を大文字・小文字の区別によって制御するという重要な設計原則をチュートリアルに反映させるためのものです。
- 大文字化された識別子:
sys.Exit
,fmt.Printf
,fmt.Print
,fmt.Println
,fmt.Sprint
,fmt.Fprintf
,syscall.Open
などは、パッケージの外部から利用されることを意図した公開APIとして設計されたため、その名前の最初の文字が大文字に変更されました。これにより、ユーザーはこれらの関数や変数がGoの標準的な可視性規則に従ってエクスポートされていることを直感的に理解できます。 - 小文字化された識別子:
newFD
,reader
,rotate13
,generate
,filter
,sieve
,request
,binOp
,run
,server
,startServer
などは、パッケージ内部でのみ使用されることを意図した非公開(unexported)の識別子として設計されたため、その名前の最初の文字が小文字に変更されました。これにより、これらの識別子がパッケージの内部実装の詳細であり、外部から直接アクセスすべきではないことが明確になります。
特に注目すべきは、doc/go_tutorial.txt
において、以前の export
キーワードに関する記述が削除され、代わりに大文字・小文字による可視性規則が詳細に説明されている点です。これは、Go言語がその設計の初期段階で、より簡潔で一貫性のある可視性制御メカニズムを採用したことを示しています。
これらの変更は、Go言語の設計思想がチュートリアルという形でユーザーに伝えられ、言語の基本的な使い方を学ぶ上で不可欠な情報となったことを意味します。
関連リンク
参考にした情報源リンク
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFTC-CaeZat92BWZ9VTnAxTr9WARJxE1TT_Nd81IUfCxXrjFxVQuncLz-I6owQkooMILcElfIMipxklIOVECQ_hsajTUtof4AUlenEGvFyRNTuCN4kvahGnHY=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQF5QxzU5LTq1dbfFCy9BhvkoN9s7fpdYFlkHk8Ue-LS2XzWqn93EdtnctGhBsh7p3MBE-H1RliIhlu_Z3ZZz53em-SGx30GE7HsSgDbcKXrgyM9dYzIzm4r8kl5bjUBHC9ZW-7605JmLvSK5hEPY7mXT0lbkFie386g2A_wrca4YpVv5485
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHe1NiWP44aGhcBn7aNjSQRpvCclVqKsDR4nEVYr2eNXXdrU3GBJFyGP_h038c8N1uqx7dxznkOYKWr6ZSmaxrb7LD6_79dnt_u411OlyiNr837RaEQAcax7TgV
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHXVvcrCnujFHRz4wbsKqqSYWDd6K37TXHUujYJun3c1ut2JHzSF03zJXhXzBRL3k8zkll8elAMHt7NLGgVYmMCiuH_XHjdeIzOmmrKlo-HBpA14t-QDhUdMABvjO4YaHJ_AThWfGYnpDaznfZ7RYvfl4_D9JqybcFgnf4FWjLuGzJRJuqdHg==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGKtwmwxB8IlgUKoklPeDo4td0uvhhPMyzwN6KuknqVuj9ds4arOvT3c5ifLPPTGhcHnbDAkqoIV8dmqFBEV6fmbOITNunENMbmwzTenujR6FPLpBZYudAVmC10xLcYCA0rVgaGTG2mSQDHkHOAdcemF36ksjSonoBIsxb2TffLwo9MvXKtM7Z5JDw=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEKMgO_eIQtXxRbtJBJWKsEZawtVP71dP0Rvrf9u8e_TAcdxyD3m8FDcytU2xgW9x2DJw4SWXSzUpyVjZi0-2--XWuqfWh4J9kGSd_Zihw5Latd5a354EuDRE77qURPcTqNFRdJ43fBxuOs6HnYYDW7g_uwwijo0AFnNUnOdCkX7fOipLUnn_uCBpXkGkvVMznbONl-Muc6Gvmq6Im-1nkjPo50Vxf2d4-RfaA6obbXb8HgDuZeRkU=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEf0BTkSujlaRo72kS5lZBSPNq5oaQpE3u4c0Hmh4epFvtKNkBnZ07bogMTC2OBmrpFovSy38tO8RY2_POATyN7U6iyj8INw9HAmmA7wMs11V9i3sE3505nCFpzQgxZ5CWN8KmoyX5iD78QuSUzh7OOFHgffBAlCrETYPjPCseQSytD1vLpL9x9tad91fK6o6lHCQ==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGZ9v4rVA_sEBF8l0nVSlESOVvoEEYdHa-rqHHHorjtiYxy9qecjk_4wOl6H-SRuAQwa719WS0xAP-KvXZflXfIHR6uGFCf_IVc0v-eiF0wO1ObYYGJua5D4TN81aBvVEXK2QnV