安全2

趣味のコンピュータ

ローカル環境(macOS)のGoとGo Playgroundで同一コードの実行結果が異なる

ここ最近ちゃんとGoやろうと思って、A Tour of Go(日本語版)をやっているんですが、Appending to a sliceの章にあるサンプルコードの実行結果がローカル環境(macOS)のGoとGo Playgroundで違う現象に遭遇してしまった。コードは以下。

  • append.go
package main

import "fmt"

func main() {
    var s []int
    printSlice(s)

    // append works on nil slices.
    s = append(s, 0)
    printSlice(s)

    // The slice grows as needed.
    s = append(s, 1)
    printSlice(s)

    // We can add more than one element at a time.
    s = append(s, 2, 3, 4)
    printSlice(s)
}

func printSlice(s []int) {
    fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}

ローカルの実行環境

$ go run append.go

len=0 cap=0 []
len=1 cap=1 [0]
len=2 cap=2 [0 1]
len=5 cap=6 [0 1 2 3 4]

Go Playground

  • The Go PlaygroundのAboutを参照

    • この記事を書いている2019/08/22現在、Goのバージョンは1.12.9とのこと
  • 実行結果

len=0 cap=0 []
len=1 cap=2 [0]
len=2 cap=2 [0 1]
len=5 cap=8 [0 1 2 3 4]

考えた原因

Goが実行される環境のOSによって結果が変わってしまうのでは?

-> DockerでLinuxのGo実行環境を作って試してみる

以下のdocker-compose.ymlでコンテナを作る。

version: "3"

services:
  golang:
    image: golang:1.12.9-alpine3.10
    tty: true
    volumes:
      - ./:/go
    environment:
      - "GOPATH=/go"

各環境でOS情報を取得してみる

以下のコードを実行。

package main

import (
    "fmt"
    "runtime"
)

func main() {
    fmt.Println(runtime.GOOS)
}
  • ローカルの実行環境(macOS)
darwin
  • The Go Playground
nacl
  • Docker上のGo実行環境
linux

naclがわからないのでググったらGo Playgroundの内部的なことを書いたGo Blogの記事を見つけた。

blog.golang.org

見つけたんですが、初学者ゆえにわからない点があまりに多いので一旦Docker上のGo実行環境での実行結果を確認します。

$ go run append.go

len=0 cap=0 []
len=1 cap=1 [0]
len=2 cap=2 [0 1]
len=5 cap=6 [0 1 2 3 4]

macのローカル環境で実行した場合と同じ実行結果。

Go Playgroundの内部的なところは難しそうなのでちょっと後で読んでみるとして、darwinlinuxで実行結果が変わらないことだけわかった。

引き続き調べようとは思うものの、誰か詳しい方がいたらご教授頂けると嬉しい・・・。