これは、なにをしたくて書いたもの?
そろそろ、少しずつGoを扱ってみようかなぁと思いまして。
触ったことがないので、今回はとりあえず簡単にインストーとエディタの設定くらいをやります。
環境
今回の環境は、こちらです。Ubuntu Linux 20.04 LTSです。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.1 LTS Release: 20.04 Codename: focal $ uname -srvmpio Linux 5.4.0-58-generic #64-Ubuntu SMP Wed Dec 9 08:16:25 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
Goをインストールする
では、Goをインストールしましょう。
Goのオフィシャルサイトを見ると、Linux環境だとtar.gz
バイナリをダウンロードしてインストールという感じになっています。
Download and install - The Go Programming Language
ですが、GitHubリポジトリにいくともう少し他の手段があるようです。
GitHub - golang/go: The Go programming language
Ubuntu LinuxだとPPAが提供されているようなので、こちらを使うことにします。
Ubuntu · golang/go Wiki · GitHub
まず、なにもしない状態でgolang
パッケージを見てみましょう。
$ apt info golang Package: golang Version: 2:1.13~1ubuntu2 Priority: optional Section: devel Source: golang-defaults Origin: Ubuntu Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> Original-Maintainer: Go Compiler Team <team+go-compiler@tracker.debian.org> Bugs: https://bugs.launchpad.net/ubuntu/+filebug Installed-Size: 12.3 kB Depends: golang-1.13, golang-doc (>= 2:1.13~1ubuntu2), golang-go (>= 2:1.13~1ubuntu2), golang-src (>= 2:1.13~1ubuntu2) Homepage: https://golang.org Download-Size: 2,900 B APT-Sources: http://jp.archive.ubuntu.com/ubuntu focal/main amd64 Packages Description: Go programming language compiler - metapackage The Go programming language is an open source project to make programmers more productive. Go is expressive, concise, clean, and efficient. Its concurrency mechanisms make it easy to write programs that get the most out of multicore and networked machines, while its novel type system enables flexible and modular program construction. Go compiles quickly to machine code yet has the convenience of garbage collection and the power of run-time reflection. It's a fast, statically typed, compiled language that feels like a dynamically typed, interpreted language. . This package is a metapackage that, when installed, guarantees that (most of) a full Go development environment is installed.
このエントリを書いている時点で、最新のGoは1.15なので少し古いです。
こちらの手順に沿って、PPAを追加します。
Ubuntu · golang/go Wiki · GitHub
$ sudo add-apt-repository ppa:longsleep/golang-backports $ sudo apt update
もう1度パッケージの情報を見てみましょう。
$ apt info golang Package: golang Version: 2:1.15-1longsleep1+bionic Priority: optional Section: devel Source: golang-defaults Maintainer: Go Compiler Team <team+go-compiler@tracker.debian.org> Installed-Size: 10.2 kB Depends: golang-1.15, golang-doc (>= 2:1.15-1longsleep1+bionic), golang-go (>= 2:1.15-1longsleep1+bionic), golang-src (>= 2:1.15-1longsleep1+bionic) Download-Size: 3,912 B APT-Sources: http://ppa.launchpad.net/longsleep/golang-backports/ubuntu focal/main amd64 Packages Description: Go programming language compiler - metapackage The Go programming language is an open source project to make programmers more productive. Go is expressive, concise, clean, and efficient. Its concurrency mechanisms make it easy to write programs that get the most out of multicore and networked machines, while its novel type system enables flexible and modular program construction. Go compiles quickly to machine code yet has the convenience of garbage collection and the power of run-time reflection. It's a fast, statically typed, compiled language that feels like a dynamically typed, interpreted language. . This package is a metapackage that, when installed, guarantees that (most of) a full Go development environment is installed.
Go 1.15が表示されました。
インストールします。
$ sudo apt install golang
確認。
$ go version go version go1.15.6 linux/amd64
試してみる
では、ちょっと動かしてみましょう。Getting Startedに沿ってみます。
Tutorial: Get started with Go - The Go Programming Language
ソースコードを作成。
hello.go
package main import "fmt" func main() { fmt.Println("Hello, World!!") }
ソースコードのフォーマット。
$ go fmt hello.go
go mod init
で、カレントディレクトリをモジュールルートとして設定します。モジュール名は、Getting Startedのままhello
と
します。
$ go mod init hello go: creating new go.mod: module hello
go.mod
というファイルが作成されます。
go.mod
module hello go 1.15
go run
で実行。
$ go run hello.go Hello, World!!
go build
で実行可能ファイルが作成されます。
$ go build hello.go
hello
というファイルができました。
$ ll 合計 2000 drwxrwxr-x 2 xxxxx xxxxx 4096 12月 18 00:05 ./ drwxrwxr-x 4 xxxxx xxxxx 4096 12月 18 00:01 ../ -rwxrwxr-x 1 xxxxx xxxxx 2034781 12月 18 00:05 hello* -rw-rw-r-- 1 xxxxx xxxxx 75 12月 18 00:04 hello.go
実行。
$ ./hello Hello, World!!
そのままドキュメントに沿って、外部パッケージを使ってみます。rsc.io/quote
というパッケージですね。
hello_quote.go
package main import ( "fmt" "rsc.io/quote" ) func main() { fmt.Println(quote.Go()) }
go run
で実行すると、初回はパッケージのダウンロードが行われます。
$ go run hello_quote.go go: finding module for package rsc.io/quote go: downloading rsc.io/quote v1.5.2 go: found rsc.io/quote in rsc.io/quote v1.5.2 go: downloading rsc.io/sampler v1.3.0 go: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c Don't communicate by sharing memory, share memory by communicating.
2回目の実行時は、ダウンロードはスキップされます。
$ go run hello_quote.go Don't communicate by sharing memory, share memory by communicating.
この時、go.mod
に外部パッケージの依存が追記されるようです。
go.mod
module hello go 1.15 require rsc.io/quote v1.5.2 // indirect
また、go.sum
というファイルもできていました。
go.sum
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y= rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
ダウンロードしたファイルは、デフォルトでは$HOME/go
配下に置かれるようですね。$GOPATH
という話らしいですが、
このあたりはそのうち調べましょう…。
$ find $HOME/go -maxdepth 6 -type f $HOME/go/pkg/mod/cache/lock $HOME/go/pkg/mod/golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c/LICENSE $HOME/go/pkg/mod/golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c/README.md $HOME/go/pkg/mod/golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c/AUTHORS $HOME/go/pkg/mod/golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c/gen.go $HOME/go/pkg/mod/golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c/.gitattributes $HOME/go/pkg/mod/golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c/CONTRIBUTORS $HOME/go/pkg/mod/golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c/PATENTS $HOME/go/pkg/mod/golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c/doc.go $HOME/go/pkg/mod/golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c/.gitignore $HOME/go/pkg/mod/golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c/CONTRIBUTING.md $HOME/go/pkg/mod/golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c/codereview.cfg $HOME/go/pkg/mod/rsc.io/sampler@v1.3.0/sampler.go $HOME/go/pkg/mod/rsc.io/sampler@v1.3.0/LICENSE $HOME/go/pkg/mod/rsc.io/sampler@v1.3.0/go.mod $HOME/go/pkg/mod/rsc.io/sampler@v1.3.0/hello.go $HOME/go/pkg/mod/rsc.io/sampler@v1.3.0/glass.go $HOME/go/pkg/mod/rsc.io/sampler@v1.3.0/glass_test.go $HOME/go/pkg/mod/rsc.io/sampler@v1.3.0/hello_test.go $HOME/go/pkg/mod/rsc.io/quote@v1.5.2/LICENSE $HOME/go/pkg/mod/rsc.io/quote@v1.5.2/README.md $HOME/go/pkg/mod/rsc.io/quote@v1.5.2/go.mod $HOME/go/pkg/mod/rsc.io/quote@v1.5.2/quote_test.go $HOME/go/pkg/mod/rsc.io/quote@v1.5.2/buggy/buggy_test.go $HOME/go/pkg/mod/rsc.io/quote@v1.5.2/quote.go $HOME/go/pkg/sumdb/sum.golang.org/latest
Goでlsp-mode
最後に、エディタの設定をしましょう。自分はEmacsを使うのと、lsp-modeでなんとかしたいところ。
エディタやIDEに関する情報は、Wikiにまとまっていました。
IDEsAndTextEditorPlugins · golang/go Wiki · GitHub
まずは、go-modeをインストール。
GitHub - dominikh/go-mode.el: Emacs mode for the Go programming language
Goでlsp-modeを使うには、goplsというものが必要そうです。
Go (gopls) - LSP Mode - LSP support for Emacs
https://github.com/golang/tools/blob/master/gopls/doc/emacs.md
というわけで、goplsをインストール。go.mod
ファイルがないディレクトリで実行する場合は、$GO111MODULE
をon
に
しないと動きませんでしたが…。
$ GO111MODULE=on go get golang.org/x/tools/gopls@latest
$PATH
を通せ、ということらしいので
You first must install gopls and put it somewhere in your PATH.
https://github.com/golang/tools/blob/master/gopls/doc/emacs.md
$HOME/go/bin
に通しておきます。
$ PATH=$HOME/go/bin:$PATH
確認。
$ gopls version golang.org/x/tools/gopls v0.6.0 golang.org/x/tools/gopls@v0.6.1 h1:vD171EDBkyUVyp9B45IYXklV/VEfbHgX0FKw0Q0dO30=
あとは、.init.el
を設定して完了です。lsp-mode、company、go-mode+lsp-mode、ですね。
;; lsp-mode (require 'lsp-mode) (setq gc-cons-threshold 100000000) (setq read-process-output-max (* 1024 1024)) (setq lsp-completion-provider :capf) (setq lsp-idle-delay 0.500) (require 'lsp-ui) (setq lsp-ui-imenu-enable t) (setq lsp-headerline-breadcrumb-enable t) ;; company (require 'company) (global-company-mode t) (setq company-idle-delay 0) (setq company-minimum-prefix-length 1) (setq company-selection-wrap-around t) (setq completion-ignore-case t) (define-key company-active-map (kbd "C-n") 'company-select-next) (define-key company-active-map (kbd "C-p") 'company-select-previous) (define-key company-active-map (kbd "C-s") 'company-filter-candidates) ;; go (use-package lsp-mode :ensure t :commands (lsp lsp-deferred) :hook (go-mode . lsp-deferred))