「Go」の版間の差分

9,628 バイト除去 、 9 か月前
M
分割
M (分割)
* ※ Go言語に「共用体」の機能は無い.
;その他
* [[Go/並列処理|並列処理]]
* [[Go/ネットワーク処理|HTTP]]
* [[Go/ファイル入出力|ファイル入出力]]
 
== ※ 以下、未分類 ==
</pre>
のようにscanner 型を使ってオブジェクトを用意して、メモリ確保のために変数を宣言し(上記コードの Scanner hensuu の部分 )、さらにその変数に nextline プロパティなどを設定するという仕組みである。
 
== メソッドとインターフェース ==
=== メソッド ===
JavaScriptなどに
オブジェクト.メソッド()
 
のように特定の「オブジェクト」なるものに所属する関数としてメソッドというものがあります。
 
Go言語では、type演算子などを使って、このようなメソッドを作成できます。
 
メソッドの書式については文章だけで説明しても難しいので、まず先にコード例を提示します。(後述で書式などを説明します。)
 
;コード例
<syntaxhighlight lang="go">
package main
 
import (
"fmt"
)
 
type kou int // 型を定義
 
func (n kou) tasugo() kou {
// 5を足すだけの処理
return 5 + n
}
 
func main() {
var n kou
var m kou
n = 7
m = n.tasugo()
fmt.Printf("%d\n", m)
 
}
</syntaxhighlight>
 
;実行結果
12
::(※ 5+7=12なので)
 
 
上記コードの書式を解説すると、下記のようになります。
 
;上記コード例の書式など
<syntaxhighlight lang="go">
package main
 
import (
"fmt"
)
 
type 型名 型
 
func (レシーバ変数 型名) メソッド名() 型名 {
return 戻り値
}
 
func main() {
var n kou
var m kou
// 初期値など
n = 7
m = レシーバ変数.メソッド()
 
fmt.Printf("%d\n", m)
}
</syntaxhighlight>
 
読者には
type 型名 型
というのが冗長に思えるかもしれませんが、しかしGo言語の仕様により、(関数ではなく)メソッドを使う際には、こう書かないと、エラーになります。(たぶん、コンパイラ作成時のいろいろな事情がありますので、気にせず、「こう書くのだ」と覚えてください。)一方、メソッドではなく関数を使うだけなら、このtypeの文は不要です。
 
 
さて、最後のほうで「fmt.Printf("%d\n", m)」とありましが、もし、ここを
fmt.Printf("%d\n", n.nibai() )
のように一度にまとめて書いても、エラーになります。
 
なので、
m = n.nibai()
fmt.Printf("%d\n", m)
のように、組み込み関数の外で、メソッドの値を、べつの変数に代入する必要があります。(よそのプログラム言語でも、似たような現象があり、こういう作業を「インスタンス」という。メモリの確保などのコンパイラ内部などの都合により、あらかじめ別の変数に代入するなどの必要がある。)
 
 
;レシーバ変数
func (n kou) tasugo() kou {
において、funcの直後の ( ) のなかの変数をレシーバ変数と言います。
 
つまり、書式は
func (レシーバ変数 型名) メソッド名() 型名 {
です。
 
本節の冒頭のコード例
func (n kou) tasugo() kou {
では、「n」がレシーバ変数です。
 
 
メソッドを呼び出すときの書式は、
レシーバ変数.メソッド()
の書式です。
 
そして、これを「インスタンス」(メモリ確保などのための事前処理)のために、別の変数(たとえばmなど)に代入する必要があるわけですから、
m = レシーバ変数.メソッド()
みたいな記述がコード中のどこかにあるコーディングをする事になるでしょう。
 
=== インターフェース ===
※ 未記述
 
== ネットワーク関係 ==
いわゆる普通のwebサイトの形式である、HTML形式のwebサイトのプロトコルは「HTTP」というプロトコルである。
 
で、そのHTTPサーバを建てる場合、localhostでいいなら
 
;サーバ側のコード例
<syntaxhighlight lang="go">
package main
 
import (
"fmt"
"net/http"
)
 
func main() {
http.HandleFunc("/", aaa)
http.ListenAndServe("localhost:8080", nil)
}
 
 
func aaa(qq http.ResponseWriter, ttt *http.Request) {
 
fmt.Fprintf(qq,"<h1>あいうえお</h1>\n" )
 
}
</syntaxhighlight>
 
でサーバが建つ。
 
 
上記コード中の「aaa」とか「qq」とか「ttt」はデタラメにつけた名前なので、この部分は他の名前でもいい。
 
 
webブラウザでアドレス「localhost:8000」にアクセスし、拡大表示された「あいうえお」が表示されていれば成功。
 
 
なお、
Fprintf
とは、ファイル入出力の読み書きの関数。Go言語は、このファイル入出力の関数を、HTTP通信にも流用している。(なおPHPも、記述方法は違うが、ファイル入出力の機能を流用する方式である。)
 
 
 
これらの処理でGo言語が一体なにをやっているかというと、ソケット通信というのをやっている。(詳しくは『[[WinSock]]』または『[[Unixソケットプログラミング]]』を参照せよ。)
 
 
 
上記コードでは「aaa」とかデタラメに変数名をつけたが、慣習的には下記コードのような変数名になる。
 
;サーバ側のコード例
<syntaxhighlight lang="go">
package main
 
import (
"fmt"
"net/http"
)
 
func main() {
http.HandleFunc("/", aaa)
http.ListenAndServe("localhost:8080", nil)
}
 
 
func aaa(w http.ResponseWriter, r *http.Request) {
 
fmt.Fprintf(w,"<h1>あいうえお</h1>\n" )
 
}
</syntaxhighlight>
 
「w」とか「r」とか何かよく分からないが、慣習的にこう書くので、その慣習に合わせておこう。
 
 
 
== ファイル入出力 ==
実行しているプログラムファイル以外の外部ファイルを読み込んだり、外部ファイルを作成したり、外部ファイルに書き込んだりすることを「ファイル入出力」と言います。
 
Go言語では "os" パッケージをインポートしないと、ファイル入出力できないです。
 
osパッケージの組み込み関数である <code> os.Create </code> 関数で、外部ファイルを作成できます。
 
<code> os.Create </code> 関数を使用する際、この関数は戻り値を2つ使用します。むりやりに戻り値を1つだけでコードを書いてもエラーになります。
 
 
<code> os.Create </code> 関数の第1引数は、正常動作時の戻り値、第2引数はエラー時に書き込まれる戻り値であると、Go言語の仕様が決まっています。
 
 
下記コードでは、わかりやすさを重視するため、ファイルのオープンのエラー時の処理を省略しています。
 
「nil」とは、よその言語でいう「ヌル」みたいなもので、データの空いている状態をあらわすモノです。
 
下記コードではエラーが起きた場合、変数 kensa はos.Createによって書き込まれるので、もはや空白ではなくなるので、
if kensa != nil {
となっているのです。関係演算子の「 != 」とは「でなければ」という意味です。
 
 
;コード例
<syntaxhighlight lang="go">
package main
 
import (
//"fmt"
"os"
)
 
func main() {
namae := "ftes.txt"
var nanka *os.File
var kensa error
nanka, kensa = os.Create(namae)
if kensa != nil {
// ひとまずダミー
}
mojiretu := []byte("書き込みテストhj4")
nanka.Write(mojiretu)
}
</syntaxhighlight>
 
 
;実行の結果
:「ftes.txt」という名前のファイルが作成されているハズ。
:そもファイル「ftes.txt」を開いて閲覧すると、「サンプル」と書かれている。
 
 
*os.File
のosの前についている記号はアスタリスクです。
 
 
text1 := []byte("書き込みテスト4")
 
の<code>[]byte</code>は、そういう予約語みたいなものです(スライス関連)。慣用句として、そのまま覚えたほうが早いです。
 
 
 
上記コードでは、予約語以外の部分を「namae」(名前)とか「nanka」(何か)とか「kensa」(検査)とかにしましたが、
 
実際のコードでは慣用的に英語で機能に近い意味の名称が使われます。
 
;コード例
<syntaxhighlight lang="go">
package main
 
import (
//"fmt"
"os"
)
 
func main() {
fname := "ftes.txt"
var file *os.File
var err error
file, err = os.Create(fname)
if err != nil {
// ひとまずダミー
}
txt := []byte("書き込みテスト3")
file.Write(txt)
file.Close()
}
</syntaxhighlight>
 
 
os.Create() 関数や os.Open() 関数によって開かれたファイルは、 Close() によって閉じることができます。閉じられたファイルは、再度 開くまでは、読み書きができない状態になっています。
 
間違えてデータを壊すことを防ぐ安全のため、なるべくファイルは使い終わったら、すぐに閉じるのが無難です。
 
 
 
Go言語の関数は、2個以上の値を返却できる。こういう風に、1つの関数が複数の値を返却できる仕組みを多値返却という。
 
ほかのプログラム言語でも、[[Perl]]や[[Python]]の関数も、あまり話題にならないが、実はそれらの言語の関数は多値返却も出来る。
 
 
;余談
2019年、エラー処理について、文法の改訂案が出された。
 
その提案は、エラー時のif文を毎回書くのは非効率なので、[[C++]]でいう try catch 構文のようなエラー処理のための例外処理の文法を搭載しようという案である。
 
だが、2019年、一度、この案は棄却された。Go1.14では採用がいったんは棄却されたが、引き続き、なんらかの改善は必要性があるとして、今後のバージョンでは注目が必要である。
 
なお、2020年現在、まだGoの最新版のバージョン番号は Go1.14 台である。
 
{{DEFAULTSORT:GO}}
733

回編集