Golang 戻り値を表す変数
Golangでは戻り値に変数を割り当てることができる。
package main import "fmt" func doSomething() (a int) { return } func main() { fmt.Println(doSomething()) }
実行すると結果は0
が返ってくる。
returnは何も返していないように見えるが以下のコードの省略だと考えれば良い。
func doSomething() int { var a int return a }
var a int
によって割り当てた変数aを初期化して関数の戻り値にするよいう一連の処理を、関数の戻り値の型に変数名を書くだけで済ませている。
関数内のローカル変数定義を短縮することができる。
Golang interface{}
interface{}は{}も含めて型の名前。
int, float64, stringなど全ての型と互換性をもっている。
var x interface{} fmt.Printf("%#v", x) // "<nil>"
のように初期値は "<nil>"
と出力される。
Goにおける"<nil>"
は具体的な値を持っていないという状態を表す特殊な値になる。
すべての型と互換性があるため以下のように書ける。
var x interface{} x = 1 x = 3.14 x = "ごー" x = [...]int{1, 2, 3}
あらゆる型を代入することができる。
interface{}はあらゆる型を汎用的に表現できるものであり、演算の対象として利用することはできない。
var x, y interface{} x, y = 1, 2 z := x + y //できない
Go 変数
Goにおけるすべての変数は型を備える。
- 値型
- 参照型
- ポインタ型
値型は整数、実数といった値そのものを格納する。 参照型はスライス、マップ、チャネルのいずれかのデータ構造。 ポインタ型は値や関数といったメモリ上の実態を、アドレス値によって間接的に表現するもの。
明示的な定義
var n int var x, y, z int var ( x, y int z string )
上記のように予約語 var , 変数名、型名の順に定義する。
異なる型や個数が違うものを代入しようとするとコンパイルエラーが発生する。
暗黙的な定義
型推論を用いて以下のように定義することができる
a := true b := 1 c := 3.14
など
関数の戻り値を利用することもできる。
func one() { return 1 } n := one()
変数の暗黙的な定義を利用した代入は1回しか許されない。
n := 1 n := 3
nに対する2回目の代入でコンパイルエラーが発生する。
演算子 := はあくまで変数を定義するための機能であり、変数への代入を実行しているものだとイメージしてはいけない。 型指定の省略や、まとめて初期値を代入できるメリットは副次的なものである。
演算子 = は再代入の制限がないため、変数への再代入には演算子 = を使う。
var a int a = 1 a = 2 b := 1 b = 2
ruby split
rubyのsplit メソッド
str.split(pattern = $;, [limit])
splitメソッドは、引数patternを区切り文字として文字列を分割し、配列を返します。引数の指定のしかたによってさまざまな分割ができます。分割できなかったときは、要素が文字列1つだけの配列を返します。
参照:
引数でデフォルト引数が設定されている
pattern = $;
$;は組み込み変数
irb(main):001:0> $; => nil
splitメソッドの引数を省略すると空白文字による分割になる
だから以下は同じ結果
irb(main):007:0> "1 2 3".split(" ") => ["1", "2", "3"] irb(main):008:0> "1 2 3".split => ["1", "2", "3"]
Elixir 開発環境
Elixirの勉強を個人的に始めたので覚書を残す。
dockerでElixirを使えるようにする
以下コマンドでdocker imageをpullする
docker pull trenpixster/elixir
docker上のelixir imageを起動する
docker run --rm -v /Users/kei/takakuda/elixir_tutorial:/elixir_tutorial -it trenpixster/elixir /bin/bash
あまりdockerを使ったこともなかったのでoptionも調べる
--rm
: コンテナ終了時に自動的にコンテナを削除する
-v
: ホスト側のディレクトリがコンテナにマウントされ、コンテナ上で作ったファイルがホストの方に残る
-it
: ターミナルでコンテナを実行できる
iexで対話シェルが動くことを確認。
Elixirのプロジェクトを作成する
mix new project
mix
はビルドツール。
以下のようにフォルダ、ファイルが作成されます
. ├── README.md ├── config │ └── config.exs ├── lib │ └── project.ex ├── mix.exs └── test ├── project_test.exs └── test_helper.exs
ここからelixirで開発していきます
gem 作り方覚書
準備
# gem自信のupdate gem update --system # bundlerのupdate gem update bundler # generatorからプロジェクト作成 bundle gem new_gem -t
-t
はテストも作成するoption
defaultでRSpec
他のgemと名前がかぶってはいけないので
gem search new_gem
で名前がかぶっていないことを確認しましょう。
雛形を作成することができたらnew_gem.gemspec
を編集します
spec.summary = %q{TODO: Write a short summary, because Rubygems requires one.} spec.description = %q{TODO: Write a longer description or delete this line.} spec.homepage = "TODO: Put your gem's website or public repo URL here."
TODOと書かれている箇所を編集していきます
summary -> サマリー
description -> 長めのサマリー
homepage -> https://github.com/takakuda/new_gem
といった感じです
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
と書かれている箇所は社内用のgemを外部に公開しないために公開して良いホストを指定する箇所です。
RubyGems.org
に公開するのでごっそりこのあたりの記述は消します。
作成したgemをlocalで確認
new_gemを作った同じ階層にテスト用のフォルダを作成し
bundle init
でGemfile
を作成します
new_gem ├── Gemfile ├── README.md ├── Rakefile ├── bin │ ├── console │ └── setup ├── lib │ ├── new_gem │ │ └── version.rb │ └── new_gem.rb ├── miura.gemspec └── spec ├── new_gem_spec.rb └── spec_helper.rb new_gem_test ├── Gemfile ├── Gemfile.lock
Gemfileでは
gem "new_gem", path: "../new_gem"
でlocalのgemをinstallします
その後にbundle
を実行
あとはtest用のfileを作成してgemをrequireで呼べば確認できます
確認後公開用にリポジトリを作成し、https://rubygems.org/でアカウントを作成して有効な状態にすればリリースの準備は完了です
リリース
リリースはgemspecのあるディレクトリでrake release
を実行
自分のプロファイルページに追加されていれば完了です! https://rubygems.org/profiles/takakuda
Rubyにおける「シンボル」ってなんだ?
結局「シンボル」ってなに…
結論から言うとシンボルはRubyの内部で整数として扱われる。2つの値が同じか調べるときなど、文字列よりも高速に処理することができる。
シンボルのほうがさらにメモリの使用効率が良いらしい。
irb(main):009:0* 'a'.object_id => 70227007054700 irb(main):010:0> 'a'.object_id => 70227010342780 irb(main):011:0> 'a'.object_id => 70227010329420 irb(main):013:0* :a.object_id => 736988 irb(main):014:0> :a.object_id => 736988 irb(main):015:0> :a.object_id => 736988
シンボルは同じシンボルであれば同じオブジェクトであるということらしい。
Stringの場合はobject_idが実行ごとに変わっている
なんで「シンボル」使ってるんだろうとか考えたことなかったな… 勉強勉強…