kurumi-bioの雑記帳

プログラミング、パソコン、ペット、 犬、お出かけ

初心者のGo言語 -19- go1.20とgo1.19のfmtパッケージの差異

こんにちは、kurumi-bioです。 2023年2月1日にGo言語のメジャーバージョンアップが行われてバージョンが1.20になりました。
今まで学習してきたfmtパッケージにも変更がありましたので調査しました。

環境

OSバージョン:Windows11 Home 22H2
Go言語のバージョン:

  1. go version go1.19.4 windows/amd64
  2. go version go1.20 windows/amd64

fmtパッケージの変更点

  1. Errorf 関数は、%w 形式の動詞の複数回の出現をサポートし、%w へのすべての引数のリストにアンラップするエラーを返します。
  2. 新しい FormatString 関数は、State に対応するフォーマット ディレクティブを復元します。これは Formatter で役立ちます。実装。

fmt.Errorf

func Errorf(format string, a ...any) error

Version: go1.19.4の説明

Errorf は、フォーマット指定子に従ってフォーマットし、エラーを満たす値として文字列を返します。

フォーマット指定子にエラー オペランドを持つ %w 動詞が含まれている場合、返されるエラーは、オペランドを返す Unwrap メソッドを実装します。複数の %w 動詞を含めたり、エラー インターフェイスを実装しないオペランドを指定したりすることは無効です。それ以外の場合、%w 動詞は %v の同義語です。

Version: go1.20の説明

Errorf は、フォーマット指定子に従ってフォーマットし、エラーを満たす値として文字列を返します。

フォーマット指定子にエラー オペランドを持つ %w 動詞が含まれている場合、返されるエラーは、オペランドを返す Unwrap メソッドを実装します。複数の %w 動詞がある場合、返されるエラーは Unwrap メソッドを実装し、引数に現れる順序ですべての %w オペランドを含む [] エラーを返します。エラー インターフェイスを実装しないオペランドを %w 動詞に指定することは無効です。それ以外の場合、%w 動詞は %v の同義語です。

説明が異なる箇所に色を付けました。
異なる点はgo1.19.4では複数の%wを使うことが禁止されていましたが、go1.20では、複数の%wの記載が可能となっています。
では、fmt.Errorfに2つの%wを指定すると、どうなるか試してみました。

<サンプルコード>ErrorfTest.go

package main

import (
    "fmt"
    "errors"
)

func main() {
    e1 := errors.New("error1")
    e2 := errors.New("error2")

    e := fmt.Errorf("%w %w", e1, e2)

    fmt.Println(e)
}

<実行結果>

go1.19.4では、二つ目の%wが表示されませんでしたが、
go1.20ですと、書式指定した通りに2つのerrorが表示されました。

<広告の下に記事が続きます。>

fmt.FormatString

func FormatString(state State, verb rune) string

FormatString は、State によってキャプチャされた完全修飾フォーマット ディレクティブを表す文字列を返し、その後に引数動詞が続きます。 (状態自体には動詞は含まれません。) 結果には先頭のパーセント記号があり、その後にフラグ、幅、および精度が続きます。欠落しているフラグ、幅、および精度は省略されています。この関数を使用すると、Formatter は、Format の呼び出しをトリガーする元のディレクティブを再構築できます。

go1.20で新規追加された関数です。
fmt.Stateがinterfaceで宣言されていて、これで正しいのかわからないのですが、 4桁の数値の書式設定を返すサンプルコードを作成しました。

<サンプルコード>FormatStringTest.go

package main

import (
    "fmt"
    "errors"
)

type FourDigit struct {}
func (f FourDigit) Write(b []byte)(int, error) {
    e := errors.New("Write error!")
    return 0, e
}
func (f FourDigit) Width()(int, bool){
    return 4, true
}
func (f FourDigit) Precision()(int ,bool){
    return 0, false
}
func (f FourDigit) Flag(c int) bool{
    return true
}

func main() {
    var f FourDigit

    var s fmt.State
    var v rune
    v = 'd'
    s = f
    fmt.Println(fmt.FormatString(s,v))
    fmt.Printf(fmt.FormatString(s,v),4)
}

<実行結果>

それっぽい書式設定文字列が返されて、fmt.Printfに渡すことができました。 こんな遠回りなことをしなくても、もっと簡単にできそうな気がしますので、 根本的に使い方が間違っている気がしました。

ちなみに、go1.19.4では「未定義」と表示されて実行不可でした。

最後までご覧いただきありがとうございます

初心者のGo言語 -18- <Getpagesize,Getpid,Getppid,Getuid,Getwd,Hostname>

こんにちは、kurumi-bioです。 第5回目のosパッケージ(標準ライブラリー)の学習です。

環境

  • Windows
    OSバージョン:Windows11 Home 22H2
    Go言語のバージョン:go version go1.19.4 windows/amd64

  • Linux
    OSバージョン:openSUSE Leap 15.4
    Go言語のバージョン:go version go1.20.1 linux/amd64

Getpagesize関数

func Getpagesize() int

Getpagesize は、基になるシステムのメモリ ページ サイズを返します。

<サンプルコード>GetpagesizeSample.go

package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println(os.Getpagesize())
}

<実行結果>

上がWindowsで下がLinuxの実行結果です。 両OSともにページサイズは4Kbという結果になりました。

Getpid関数

func Getpid() int

Getpid は、呼び出し元のプロセス ID を返します。

<サンプルコード>GetpidSample.go

package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println(os.Getpid())
}

<実行結果>

実行するとプロセスIDが表示されました。
このプログラムですと一瞬で終わってしまうので正しい値か確認できません。
プログラムにtime.Sleep関数を追加して処理を1分間終わらせないようにしました。

<サンプルコード>GetpidSampleK1.go

package main

import (
    "fmt"
    "os"
    "time"
)

func main() {
    fmt.Println(os.Getpid())
    time.Sleep(time.Minute * 1)
}

<実行結果>

タスクマネージャの詳細画面を見ると、
プロセスID 8424のプロセスは、GetpidSampleK1.exeとなっています。
go runコマンドは、ビルドしてEXEにしてから実行していることがわかります。

Getppid関数

func Getppid() int

Getppid は、呼び出し元の親のプロセス ID を返します

<サンプルコード>GetppidSample.go

package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println(os.Getppid())
}

<実行結果>

2回実行しましたが、2回とも別のプロセスIDが表示されました。
ひとつ前でgo runコマンドを実行すると「ビルドして実行」となっていることが判明しました。 ですので、表示されている親プロセスIDは、「ビルドして実行」のプロセスIDだと思われます。
では、試しにtime.Sleep関数を追加して実行してみます。

<サンプルコード>GetppidSampleK1.go

package main

import (
    "fmt"
    "os"
    "time"
)

func main() {
    fmt.Println(os.Getpid())
    fmt.Println(os.Getppid())
    time.Sleep(time.Minute * 1)
}

<実行結果>

親プロセスは、go.exeでした。go runを実行しているの当然なのですが、 ビルドしたモジュールが終わるのを待っているのが意外でした。

ちなみに、ビルドしてexe形式にしてから実行すると、親プロセスがコマンドプロンプトになるので、 何度実行しても親プロセスIDは同じになります。

<広告の下に記事が続きます。>

Getuid関数

func Getuid() int

Getuid は、呼び出し元の数値ユーザー ID を返します。 Windows では -1 を返します。

<サンプルコード>GetuidSample.go

package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println(os.Getuid())
}

<実行結果>

上がWindowsで下がLinuxの実行結果です。 Linuxは、ユーザIDが取得できています。

Getwd関数

func Getwd() (dir string, err error)

Getwd は、現在のディレクトリに対応するルート パス名を返します。 (シンボリック リンクにより) 複数のパスを介して現在のディレクトリに到達できる場合、Getwd はそれらのいずれかを返す場合があります。

<サンプルコード>GetwdSample.go

package main

import (
    "fmt"
    "os"
)

func main() {
    s, e := os.Getwd()
    if e != nil {
        fmt.Fprintf(os.Stderr, "os.Getwd Error: %v \n", e)
        os.Exit(1)
    }
    fmt.Println(s)
}

<実行結果>

パス名が取得できました。

Hostname関数

func Hostname() (name string, err error)

Hostname は、カーネルによって報告されたホスト名を返します。

<サンプルコード>HostnameSample.go

package main

import (
    "fmt"
    "os"
)

func main() {
    s, e := os.Hostname()
    if e != nil {
        fmt.Fprintf(os.Stderr, "os.Hostname Error: %v \n", e)
        os.Exit(1)
    }
    fmt.Println(s)
}

<実行結果>

ホスト名が取得できました。

最後までご覧いただきありがとうございます

自作PCにGALAKURO GK-RTX3060Tiを付けました

こんにちは、kurumi-bioです。

自作PCにグラフィックボードを付けました。
玄人志向 GALAKURO GK-RTX3060Ti-E8GB/WHITE/LHR
です。


GALAKURO GK-RTX3060Tiの中身

GK-RTX3060Tiは、重厚なクッション材で守られています。 簡単な説明書(英語)とRGBケーブルが付属していました。 ミドルレンジですが、思っていたよりも大きいです。


PCケース内

2スロット分使って長さもそこそこあるので、一気に窮屈な感じになりました。 白色で統一したのですが、スイッチ等のケースから出ているケーブルが黒いのが残念です。


GK-RTX3060Tiが場所をとるので、配線はすべて裏側を通すようにしました。 CPUの電源ケーブルはグルリと遠回りして丁度よい感じになりました。


2つ目のSSDスロットはグラフィックボードを外さないと交換できなくなりました。 さらに一番下のスロットも使えない感じです。使うことは無いと思いますが。


念のため長尾製作所のマグネット式VGAサポートステイ(N-VGASTAY03-XS-WH)で支えています。


ベンチマーク

Windows システム評価ツール(WinSAT)の評価結果です。左がGALAKURO GK-RTX3060Tiを取り付ける前です。 グラフィックスが8.1だったのが9.9までアップして、プロセッサとメモリが一番低いサブスコアになってしまいました。 メモリーオーバークロックで改善する余地がありそうなので、近いうちに試してみたいと思います。


FINAL FANTASY XVベンチマークの結果です。
GK-RTX3060Tiを取り付ける前は、動作困難でした。

フルHDは、非常に快適(12059)。 4K UHDTVでも、標準品質なら快適(6181)というスコアになりました。 Dell G5 5590が、フルHDの標準品質でやや快適(4922)だったことを考えると十分満足な数値だと思います。

kurumi-bio.hatenablog.com

最後までご覧いただきありがとうございます

無料はてなブログでGoogle AdSenseに1回目で合格しました。

こんにちは、kurumi-bioです。
ネットで先駆者の情報を得て必要な対策を行うことができたため、1回でGoogle AdSenseに合格しました。
頂いてばかりでは申し訳ないので、自身の対応を記載しますので参考にしてください。

申請から結果が出るまでの期間

昨日(2023年2月19日)にGoogle AdSenseの有効化の通知か来ました。
Google AdSenseの申請は、 2023年2月4日に行いましたので、結果がでるまで15日掛かりました。
2週間から4週間掛かると記載されていましたので妥当な数値だと思います。

基本データ(2023/2/19現在)

項目
ブログ開始日 2023年1月5日
投稿数 33件
投稿日数 32日
PV数 1桁/日

Google AdSenseに申請するために行ったこと

  • お問い合わせフォームの作成
  • プライバシーポリシーの策定
    上記二つは、規約に記載されていますので必須です。

  • グローバルメニューの作成
    お問い合わせフォームプライバシーポリシーを適宜参照可能にするために必要かと思われます。

  • Google アナリティクス

  • Google Search Console
    上記二つは、審査には不要と思われますが、後々解析することを考えると早めに登録してデータを蓄積した方が無難かと思われます。

その他の考察

※)自身のことを鑑みて記載していますので、正解とは程遠い可能性もあります。その点は予めご了承ください。

  1. 無料版のはてなブログでは、Google AdSenseの申請が通らない
    本ブログは、無料のはてなブログです。ですので無料のはてなブログでもGoogle AdSenseの有効化が可能です。

  2. 広告が入っていると申請が通らない
    無料のはてなブログですので広告が入った状態でしたが有効化できました。 ただし、Google AdSenseの審査で既存広告についてどのような判断があったのか不明ですので、申請が通るまでは他社の広告は入れない方が無難と思われます。

  3. ブログを開始してから数か月経過しないと申請が通らない
    はてなブログを開始して一か月後に申請して有効化が可能になりましたので、ブログ作成期間は審査に与える影響は少ないと思われます。

  4. 投稿数が20件を超えていないと申請が通らない
    Google AdSenseを申請したときの投稿数は21件でした。有効化の通知が来たときは33件でした。ですので、ある程度の投稿数は必要かと思われます。

  5. 毎日投稿しないと申請が通らない
    毎日投稿は無理でしたが、投稿が無い日が連続にならないように意識しました。

  6. 投稿内容により申請が通らない
    ブログ初心者ですので内容は薄いです。ただ、自身で調べたこと行ったことを投稿していますのでオリジナリティがあるので申請が通った可能性があります。

後は、自身がどれだけ長くブログを投稿し続けることができるかですね。

先週のくるみ(2023.02.19)

こんにちは、kurumi-bioです。
2月12日(日)~18日(土)のくるみの生活雑記です。

先週のくるみの様子

  • 散歩
    今週も、朝の散歩は同じ公園に向かうことが多かったです。公園の周りの道を徐々に開拓してさらに奥の公園を発掘しました。 散歩時間は、暖かくなってきたので少し伸びてきて朝の散歩は、平均約1時間15分くらいです。

  • 朝ご飯
    朝の散歩の前にご飯を食べたのは、7日間のうち2日だけでした。夕方になっても食べないときは、水に浸しておくと食べ始めます。家に来てからずーっと同じフードなので、少し飽きているかもです。

  • 他人
    夕方の散歩で、久々にワンコ仲間(5~6匹)に会って、楽しくワチャワチャやってました。飼い主さんが近くにいても、あまり気にせず遊んでいました。これから暖かくなって、散歩仲間に会う機会も増えて、他人の苦手感も減っていくと思います。

先週の写真


熱心に匂いを嗅ぐ くるみ
撮影日 2023年2月15日
散歩中は、色々な匂いを嗅ぐのが楽しいみたいで、鼻がすり減るんじゃないかと思うくらいずーっと地面に鼻をつけて歩いています。


正面から撮影した くるみ
撮影日 2023年2月15日
正面から撮影できた貴重な一枚です。普段はカメラ(スマホ)を向けると違う方向に顔を向けるのですが、この時はカメラ(スマホ)を向けても、じーっとこっちを見てました。


何かを見つめる くるみ
撮影日 2023年2月17日
朝五時です。まだ暗いです。こんな感じでしばらく立ち止まってから踵を返してスタスタと戻る時が、稀にあります。自分の目だと何も見えないのですが、この先に何がいたのか気になります。


草を吟味する くるみ
撮影日 2023年2月18日
おなかの調子が悪い時に食べる草です。今の時期は生えている場所が少ないのですが、かなり離れた場所でも見つけてきます。匂いで生えてる場所がわかるみたいです。


日向ぼっこの くるみ
撮影日 2023年2月18日
久々のポカポカ陽気で庭で日向ぼっこをしてました。カメラ(スマホ)を向けたら起きてしまって、ちょっと寝ぼけ顔です。


庭で寝ている くるみ
撮影日 2023年2月18日
日差しが気持ちよさそうです。


最後までご覧いただきありがとうございます

初心者のGo言語 -17- <Expand,ExpandEnv,Getegid,Getenv,Geteuid,Getgid,Getgroups>

こんにちは、kurumi-bioです。
第4回目のosパッケージ(標準ライブラリー)の学習です。

osパッケージはWindowsで使用できない関数があります。
その場合は、Linux(openSUSE)で出力した結果も併せて記載します。

環境

  • メイン
    OSバージョン:Windows11 Home 22H2
    Go言語のバージョン:go version go1.19.4 windows/amd64

  • サブ
    OSバージョン:openSUSE Leap 15.4
    Go言語のバージョン:go version go1.20.1 linux/amd64

Expand関数

func Expand(s string, mapping func(string) string) string

Expand は、マッピング関数に基づいて文字列内の ${var} または $var を置き換えます。たとえば、os.ExpandEnv(s) は os.Expand(s, os.Getenv) と同等です。

<サンプルコード>ExecutableSample.go

package main

import (
    "fmt"
    "os"
    "strconv"
)

func main() {
    m := func(s string) string {
        var i int
        i, e := strconv.Atoi(s)
        if e != nil {
            fmt.Fprintf(os.Stderr, "strconv.Atoi Error: %v \n", e)
            return "unknown"
        }
        if i < 3 {
            return "baby"
        } else if i < 12 {
            return "child"
        } else {
            return "adult"
        }
    }
    fmt.Println(os.Expand("$13 / ${13}", m))
}

<実行結果>

m := func(s string) string {*<途中省略>*}の部分がマッピング関数です。
年齢(文字列)を受け取って、年齢に応じた区分を返すマッピング関数にしています。

fmt.Println(os.Expand("$13 / ${13}", m))の部分でマッピング関数から戻ってきた値を出力しています。 ${var} または $var と記載されていたので両方とも試してみましたが、数字の場合{}で囲まないと一文字だけが引数となるので注意が必要です。

ExpandEnv関数

func ExpandEnv(s string) string

ExpandEnv は、現在の環境変数の値に従って、文字列内の ${var} または $var を置き換えます。未定義の変数への参照は、空の文字列に置き換えられます。

<サンプルコード>ExpandEnvSample.go

package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println(os.ExpandEnv("[$PROCESSOR_ARCHITECTURE] / [${PROCESSOR_ARCHITECTURE}]"))
    fmt.Println(os.ExpandEnv("[$OS] / [${OS}]"))
    fmt.Println(os.ExpandEnv("[$NON] / [${NON}]"))
}

<実行結果>

文字列の場合は、{}で囲まなくても文字の切れ目までが引数となります。 存在しない環境変数を引数にすると空文字になります。

Getegid関数

func Getegid() int

Getegid は、呼び出し元の数値の実効グループ ID を返します。 Windows では -1 を返します。

<サンプルコード>GetegidSample.go

package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println(os.Getegid())
}

<実行結果>

(上)Windowsでは-1が返ってきました。
(下)Linuxでは、実効グループ IDが取得できました。

Getenv関数

func Getenv(key string) string

Getenv は、キーによって指定された環境変数の値を取得します。変数が存在しない場合は空になる値を返します。空の値と設定されていない値を区別するには、LookupEnv を使用します

<サンプルコード>GetenvSample.go

package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println(os.Getenv("OS"))
}

<実行結果>

環境変数OSの値が取得できました。

<広告の下に続きます。>

Geteuid関数

func Geteuid() int

Geteuid は、呼び出し元の数値有効ユーザー ID を返します。 Windows では -1 を返します

<サンプルコード>GeteuidSample.go

package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println(os.Geteuid())
}

<実行結果>

(上)Windowsでは-1が返ってきました。
(下)Linuxでは、ユーザIDが取得できました。

Getgid関数

func Getgid() int

Getgid は、呼び出し元の数値グループ ID を返します。 Windows では -1 を返します。

<サンプルコード>GetgidSample.go

package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println(os.Getgid())
}

<実行結果>

(上)Windowsでは-1が返ってきました。
(下)Linuxでは、グループ IDが取得できました。

Getgroups関数

func Getgroups() ([]int, error)

Getgroups は、呼び出し元が属するグループの数値 ID のリストを返します。 Windows では、syscall.EWINDOWS を返します。可能な代替手段については、os/user パッケージを参照してください。

<サンプルコード>GetgroupsSample.go

package main

import (
    "fmt"
    "os"
)

func main() {
    i, e := os.Getgroups()
    if e != nil {
        fmt.Fprintf(os.Stderr, "os.Getgroups Error: %v \n", e)
        os.Exit(1)
    }

    for j, k := range i {
        fmt.Printf("i[%d]=%d\n", j, k)
    }
}

<実行結果>

(上)Windowsではエラーになりました。
(下)Linuxでは、グループ IDが一つ取得できました。複数返ってこなかったのはグループの設定の仕方が悪いかと思います。
(下)Linuxでは、グループ IDが2つ取得できました。ユーザーとグループを再作成したら複数取得できるようになりました。

最後までご覧いただきありがとうございます

初心者のGo言語 -16- <DirFS,Executable,Exit>

こんにちは、kurumi-bioです。
第3回目のosパッケージ(標準ライブラリー)の学習です。

環境

OSバージョン:Windows11 Home 22H2
Go言語のバージョン:go version go1.19.4 windows/amd64

DirFS関数

func DirFS(dir string) fs.FS

DirFS は、ディレクトリ dir をルートとするファイルのツリーのファイル システム (fs.FS) を返します。 DirFS("/prefix") は、オペレーティング システムに対して行う Open 呼び出しが "/prefix" で始まることのみを保証することに注意してください。DirFS("/prefix").Open("file") は os.Open と同じです。 (「/プレフィックス/ファイル」)。そのため、/prefix/file が /prefix ツリーの外側を指すシンボリック リンクである場合、DirFS を使用しても、os.Open を使用した場合よりもアクセスが停止しません。さらに、相対パス DirFS("prefix") に対して返される fs.FS のルートは、後で Chdir を呼び出すことによって影響を受けます。したがって、ディレクトリ ツリーに任意のコンテンツが含まれている場合、DirFS は chroot スタイルのセキュリティ メカニズムの一般的な代替手段にはなりません。 ディレクトリ dir は "" であってはなりません。 結果は fs.StatFS を実装します。

<フォルダ構成>
下記のようなツリー構成のディレクトリに対してos.DirFS関数を実行してみました。

<サンプルコード>DirFSSample.go

package main

import (
    "fmt"
    "io/fs"
    "os"
)

func main() {
    f := os.DirFS("e:/temp")
    de, e := fs.ReadDir(f, "b")
    if e != nil {
        fmt.Fprintf(os.Stderr, "fs.ReadDir Error: %v \n", e)
    } else {
        fmt.Printf("fs.ReadDir success\n")
    }
    for _, d := range de {
        fmt.Println(d.Name())
    }
}

<実行結果>

os.DirFS("e:/temp")で、e:/tempをルートとしたツリーのファイル システムを取得しています。 取得したファイルシステム
func ReadDir(fsys FS, name string) ([]DirEntry, error)
の引数として渡しています。 この時に"b"という名前を指定していますので、bフォルダの一覧が取得できました。

では、os.DirFsにディレクトリではなくファイルを指定したらどうなるのでしょか。

<サンプルコード>DirFSSampleK1.go

package main

import (
    "fmt"
    "io/fs"
    "os"
)

func main() {
    f := os.DirFS("e:/temp/d.txt")
    de, e := fs.ReadDir(f, "d.txt")
    if e != nil {
        fmt.Fprintf(os.Stderr, "fs.ReadDir Error: %v \n", e)
    } else {
        fmt.Printf("fs.ReadDir success\n")
    }
    for _, d := range de {
        fmt.Println(d.Name())
    }
}

<実行結果>

os.DirFS関数ではエラーにならないで、fs.ReadDir関数で次のエラーが発生しました。
open e:/temp/d.txt\d.txt: The system cannot find the path specified.
「open e:/temp/d.txt\d.txt: 指定されたパスが見つかりません。」
os.DirFS関数は、パスを生成しているだけの感じがします。

Executable関数

func Executable() (string, error)

Executable は、現在のプロセスを開始した実行可能ファイルのパス名を返します。パスがまだ正しい実行可能ファイルを指しているという保証はありません。シンボリック リンクを使用してプロセスを開始した場合、オペレーティング システムによっては、結果がシンボリック リンクまたはそれが指すパスになる場合があります。安定した結果が必要な場合は、path/filepath.EvalSymlinks が役立つ場合があります。 Executable は、エラーが発生しない限り絶対パスを返します。 主な使用例は、実行可能ファイルに関連するリソースを見つけることです。

<サンプルコード>ExecutableSample.go

package main

import (
    "fmt"
    "os"
)

func main() {
    s, e := os.Executable()
    if e != nil {
        fmt.Fprintf(os.Stderr, "os.Executable: %v \n", e)
    } else {
        fmt.Printf("Path=[%s]\n", s)
    }
}

<実行結果>

go runコマンドは、自動でビルドして実行されますので「実行可能ファイルのパス名」は、テンポラリーフォルダに生成されたExecutableSample.exeになります。

ですので、下記の通りgo buildコマンドで予めビルドしてexeを作成することで、実行した場所のファイルパスが取得できます。

Exit関数

func Exit(code int)

Exit は、現在のプログラムを特定のステータス コードで終了させます。通常、コード ゼロは成功を示し、ゼロ以外はエラーを示します。プログラムはすぐに終了します。遅延関数は実行されません。 移植性のために、ステータス コードは [0, 125] の範囲にある必要があります。

<サンプルコード>ExitSample.go

package main

import "os"

func main() {
    os.Exit(0)

}

<実行結果>

指定したステータスコードで終了していることがわかりました。 では、エラーのステータスコードで終了するとどうなるでしょうか。

<サンプルコード>ChtimesSample.go

package main

import "os"

func main() {
    os.Exit(10)
}

<実行結果>

エラーのステータスコードで終了すると、その値が出力されます。 ですが、%ERRORLEVEL%値が1になっています。なぜステータスコードが変わるのか不思議です。

では、go buildコマンドで予めビルドしてexeを実行するとどうなるでしょうか。

<実行結果>

ステータスコードが出力されなくなり、%ERRORLEVEL%でステータスコードの取得ができました。 go runコマンドは簡易的な実行という事でしょうか。

最後までご覧いただきありがとうございます