チュートリアル(Echo)

もう少しGo言語の勉強。てか凄いよねGo言語が発表されて、それ程、日にちが経っていないのにあちこちでGo言語を利用したコードが書かれているし、その中には凄くハイレベルなものもあるし、なんでそこまで理解できているのって感心しております。

でちょっとチュートリアルにあるEchoってのを書いてみた。
ソースコードまんまコピーで動作確認。

package main

import (
    "os";
    "flag";
)
var omitNewline = flag.Bool("n", false, "don't print final newline")

const (
    Space = " ";
    Newline = "\n";
)

func main() {
    flag.Parse();
    var s string = "";
    for i := 0; i < flag.NArg(); i++ {
        if i > 0 {
            s += Space
        }
        s += flag.Arg(i);
    }
    if !*omitNewline {
        s += Newline
    }
    os.Stdout.WriteString(s);
}

実行すると、引数で渡した文字列がスペース区切りで表示されます。

$ 8g echo.go
$ 8l echo.8
$ ./8.out aaaa bbbb cccc dddd
aaaa bbbb cccc dddd
$

だから、echoなんでしょうね。
「package main」はいいとして、「import」はライブラリをインポートしている。見た瞬間わかんなかったよ。なんか変な書きかたしているし、「hello」のときとは違ってたんで戸惑った。

import (
  "os";
  "flag";
)

import "os";
import "flag";

と同意なの?まとめて書きましたって事なんだろうが、個人的にはライブラリを1つ1つ「import」で記述する方が分かりやすいかな、でも毎回「import」書くの面倒だからまとめたんだろうね。Javaではeclipseが自動でやってくれるから気にもした事無いよね。

const (
  Space = " ";
  Newline = "\n";
)

「const」は定数って事だろう。それ以外の何者でもないと思う。先頭大文字にするのが決まりなのかな?良くわからんね。

mainの中身を見ていく。

  flag.Parse()

「flag」ライブラリはってライブラリなの?モジュール?ヘッダーファイル?呼び方がわからんよね。まあいいや、「flag」はコマンドライン上より与えられた引数を操作するライブラリって事でいいのかな?「flag.Parse()」で引数を分割し配列に入れているんだろう。多分。

  flag.NArg()

で引数の個数を取得でき、

  flag.Arg(i)

で引数の各要素にアクセスできるわけだ。へ〜

あと変数宣言に関して

var s string = ""
var s = ""
s := ""

どんどん省略できます。ん〜なんで変数宣言の形にたくさん種類があるのかな?1つでと思うのだが、型をはっきりさせたいなら「var s string = ""」で十分だと思う。動的型つけであれば「s := ""」で十分だと思う。真ん中はなんだよ。ちょっと嫌だな。その時々で使い分けができるのは良いのかもしれないが、なんで3つもあるの?この辺がPython、C、C++を混ぜたって所以かな?

後はfor文やif文なんだけど

  for i := 0; i < flag.NArg(); i++ {
    if i > 0 {
      ・・・
    }
  }

まあ、見たら動作は分かると思うのだが、見慣れないよね〜不自然だよ。変だよ〜「(...)」で括られているのを見慣れているので変に感じる。でPythonみたいにネストで決まるってわけじゃないのね。なんか不思議な感じがするよ。

コード自体はそれ程難しくないね。コマンドラインから渡された引数を1つ1つ取ってきてスペースでつなげて1つの文字列にして、そいつを表示しているだけなんだけど、

var omitNewline = flag.Bool("n", false, "don't print final newline")

これが何を意味しているのか分からない?何これさっぱりだ。

分からん事は置いといて〜

  fmt.Printf("%s\n", os.Args);
  → %s([]string=[./8.out aaaa bbbb cccc dddd])

と表示されたよ。という事は、

  fmt.Printf("%s\n", os.Args[0])
  → ./8.out
  fmt.Printf("%s\n", os.Args[1])
  → aaaa

なにげにC言語の考え方は役に立ちそう。「os」ライブラリから引数を扱えるんですね。ただ、引数の数をどうやって取得するのかわからん。できると思うんだが・・・

エラーが発生した場合は

  os.Exit(1)

を返しましょう。何も返さない事が正常とのこと。ちょっと面白いね。