読者です 読者をやめる 読者になる 読者になる

chikuchikugonzalezの雑記帳

趣味とか日記とかメモとか(∩゚д゚)

cosplayコマンドをGo言語で書き直した話

開発 Go

以前 カジュアルに環境変数を変えたcmdを動かすためにcosplayコマンド作った - chikuchikugonzalezの雑記帳 という記事で cosplay とかいうコマンド作ったんですが、このたびGo言語をやることになったのでキャッチアップも兼ねて移植してみてた。

↓違い

cosplay cosplay2
言語 C# Go言語
環境 コマンドプロンプト コマンドプロンプト, PowerShell (仮)

で、ちょろちょろハマったのでそのメモを残しておこうかと

interfaceとstructのあれ?ってなったとこ

Go言語の構造体にメソッドを追加するときってだいたい以下のように書くらしいので、それに従ってました。

type Hoge struct {}
func (self *Hoge) Fuga() { /* なんかする */ }

で、インターフェイス使うとあたかも同じ型のように使える、ってことでサブコマンドの実装に使ったり。
そしたらなんか作法が違いましてね

package main

type Hoge interface {
	Hoge()
}

type HogeHoge struct {}

// ポインタダメだって
//func (self *HogeHoge) Hoge() { }

// こっち
func (self HogeHoge) Hoge() { }

func hoge(hoge Hoge) {}

func main() {
	var h = HogeHoge{}
	hoge(h)
}

違いがわからん(´・ω・`)

os.Getenv/os.Setenv/os.Environ

こっちがエッ(゚Д゚≡゚Д゚)マジ?ってなったやつ。Windowsの仕様とかも絡んでるかもしれん。

os/execパッケージ使うとプロセスを起動できるんですが、そのときに環境変数を指定しようとするとこんなことになります。

func run() {
	cmd = exec.Command("notepad.exe")
	env = []string{"hoge=fuga"}
	cmd.Env = env
	cmd.Run()
}

単に'key=value'形式の文字列が必要ってことなんですが、ここでねぇ(´・ω・`)

func run() {
	var cmd = exec.Command("cmd.exe")
	var env = []string{"hoge=fuga", "HOGE=FUGA"}
	cmd.Env = env
	cmd.Stdin  = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Run()
}

このようにして起動したcmdでsetをたたいて環境変数を見るとこうなります

C:\>set
COMSPEC=C:\WINDOWS\SysWOW64\cmd.exe
hoge=fuga
HOGE=FUGA
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC
PROMPT=$P$G

C:\>

hogeHOGEが別扱いかよ( ゚Д゚)

なお、os.Setenvとかのほうはこんなことにならんかった。

あと気になってcmd起動して

C:\> set Hoge=Fuga
C:\> set HOGE=FUGA

したけど、その結果は「Hoge=FUGA」だった

その他

mapのコピーってどうやるのがいいのかねぇ