constant xxx truncated to integerについて
Goにおける定数(constant)は定義がかなり緩い型になっており、 それを含んだ式や代入を行う場合明示的に型を指定する必要がある。
上記質問で触れられているリンクを雑&かなり適当な意訳してみた
Conversions are required when different numeric types are mixed in an expression or assignment. For instance, int32 and int are not the same type even though they may have the same size on a particular architecture.
型の異なる数値型が一つの式や代入内に現れる場合、型変換が要求される。例えば、int32とint型はとあるアーキテクチャーでは同じサイズを持つかもしれないが、同じ型ではない。
Why does Go not provide implicit numeric conversions? The convenience of automatic conversion between numeric types in C is outweighed by the confusion it causes. When is an expression unsigned? How big is the value? Does it overflow? Is the result portable, independent of the machine on which it executes? It also complicates the compiler; “the usual arithmetic conversions” are not easy to implement and inconsistent across architectures. For reasons of portability, we decided to make things clear and straightforward at the cost of some explicit conversions in the code. The definition of constants in Go—arbitrary precision values free of signedness and size annotations—ameliorates matters considerably, though.
A related detail is that, unlike in C, int and int64 are distinct types even if int is a 64-bit type. The int type is generic; if you care about how many bits an integer holds, Go encourages you to be explicit.
A blog post titled Constants explores this topic in more detail.
何故Goは暗黙的に数値変換を行ってくれないのか C言語のように異なる数値型を意識することなく変換することは便利ですが、それ以上に混乱をもたらします。 符号なしの型を用いた場合はどうなるでしょう?値がものすごく大きな値だったら?その値はオーバーフローするの?結果は動作するアーキテクチャに依存するのでしょうか?これらの問題はコンパイラーにとっても問題です。「一般的」な数値型変換を実装するのは容易ではありませんし、アーキテクチャ依存です。我々は移植性の観点から問題を明確化することにし、素直にコード中で明示的な変換を行うことにしました。ですから、Go言語における定数の定義は任意の精度を持つ値で、それは符号あり、なし・サイズなどを定義しておらず、問題をかなりわかりやすくしています。
このことに関して詳しく言うと、Cと違って、intとint64はたとえそれらが同じビットサイズを持っていても全く違う型とみなされます。int型は汎用型であり、アーキテクチャ依存です。もしintegerのbitサイズが重要ならば、Go言語では明示的な型を使用するべきでしょう。
ブログ記事Constantsではこのトピックについてさらに詳細に説明しています。
メモ
文と式
- 文
- 値を持たない
- 式
- 値を持つ
Goのgc
最後にGCされた時に確保されたメモリの使用量の倍になった時にGCが走る
なぜMapが毎回ランダムな値を返すのか?
- Keyを取得して意図したValueを取得するために、Keyを明示的にソートすることを強制させるため?
サーバにアクセスした際、handlerが二回呼ばれている気がする
- ブラウザが二回アクセスしている(最初にfavconを取りに行ってる)
公開される名前(基準は英単語の大文字・小文字だけなのか。記号・日本語だとどうなるか。)
- Unicode class Lu(Letter Upper Case)に属していれば公開
- Luカテゴリに属する文字一覧
goにおけるリテラル宣言
heap, stackの割つけ
- コンパイラが変数のスコープを見てheapにとるか、stackにとるか決定する
heapを使用する場合:変数の生存期間が関数を抜けてるため
func f() *int{ v := new(int) return v }
stackを使用する場合
func f() { v := new(int) ... }
new
パラメータの型文メモリを確保して、ゼロ値を埋めてそのアドレスを返す
実行順序の定義 参照:Order of evaluation
Order of evaluation At package level, initialization dependencies determine the evaluation order of individual initialization expressions in variable declarations. Otherwise, when evaluating the operands of an expression, assignment, or return statement, all function calls, method calls, and communication operations are evaluated in lexical left-to-right order. For example, in the (function-local) assignment y[f()], ok = g(h(), i()+x[j()], <-c), k() the function calls and communication happen in the order f(), h(), i(), j(), <-c, g(), and k(). However, the order of those events compared to the evaluation and indexing of x and the evaluation of y is not specified. a := 1 f := func() int { a++; return a } x := []int{a, f()} // x may be [1, 2] or [2, 2]: evaluation order between a and f() is not specified m := map[int]int{a: 1, a: 2} // m may be {2: 1} or {2: 2}: evaluation order between the two map assignments is not specified n := map[int]int{a: f()} // n may be {2: 3} or {3: 3}: evaluation order between the key and the value is not specified At package level, initialization dependencies override the left-to-right rule for individual initialization expressions, but not for operands within each expression: var a, b, c = f() + v(), g(), sqr(u()) + v() func f() int { return c } func g() int { return a } func sqr(x int) int { return x*x } // functions u and v are independent of all other variables and functions The function calls happen in the order u(), sqr(), v(), f(), v(), and g(). Floating-point operations within a single expression are evaluated according to the associativity of the operators. Explicit parentheses affect the evaluation by overriding the default associativity. In the expression x + (y + z) the addition y + z is performed before adding x.
結果変数
func foo() (x, y int) { //x, yはfooのローカル変数0値に初期化されている return 100, 150 // x = 100, 150 } //double関数が返す値を結果変数resultを用いてロギング func double(x int) (result int) { defer func() { fmt.Printf("return %v", result)} return x + x }
goでクロスコンパイル
ブラウザ操作を自動化するgoライブラリ
goのパッケージインポート
イメージ
go run はこれらをバックで実行させているに過ぎない。 各ツールをカスタマイズすることで(普通はしないけど、、、googleはしてる)、環境に合わせたgoの実行環境を用意することができる
レキシカルスコープの落とし穴
プログラミング言語Go P160参照
Go1.7からSSA(Statoc Single Assignment)が導入
queryの処理方法
func main() { http.HandleFunc("/", handler) log.Fatal(http.ListenAndServe("localhost:8000", nil)) } func handler(w http.ResponseWriter, r *http.Request) { query := r.URL.RawQuery v, _ := url.ParseQuery(query) s := v.Get("cycles") i, _ := strconv.Atoi(s) anime.Lissajous(w, i) }
localhost:8000/?cycles=2
でs = “2"となる。
便利なExample
Goには標準出力をテストするための便利な仕組みがある
テスト対象のコード
package main import ( "fmt" "os" "strings" ) func main() { echo() } func echo() { fmt.Println(strings.Join(os.Args[0:], " ")) }
テストコード
package main import "os" func ExampleEcho() { os.Args = []string{"test", "test"} echo() // Output: // test test } func ExampleFailEcho() { os.Args = []string{"something", "toDo"} echo() // Output: // yatta }
結果
--- FAIL: ExampleFailEcho (0.00s) got: something toDo want: yatta FAIL exit status 1 FAIL _/Users/ono/dev/go/goRepo/ch01/ex01 0.007s
テストメソッド名をExampleで開始して、
//Output:コメントの次の行に
期待される標準出力の結果をコメントで記述すれば良い
// Output: // 期待される標準出力
シンプルすぎて若干珍妙に感じてしまう
【Go学習記録】Goルーチンさわり
javaで言う所のthreadがチャンネルというらしい
大雑把な使用方法
func main { stringChanel := make(chan string) //string型のデータを取り扱うチャンネルを生成する // intChanel := make(chan int) go useStringChanel(stringChanel) //スレッドの生成 fmt.Println(<-stringChanel) //チャンネルからデータの取り出し } func useStringChanel(ch chan <- string) { ... ch <- "Set string to chanel" }
実践的な使用方法は後の章で紹介されるようなので、とりあえず今の所はこんなもんでいいか
大由彰(Akira Daiyoshi)というベーシスト
大由彰という偉大なベーシストがいた
唸るベースという表現がこれ程の似合うベーシストはいないと思っている
ただ、近年演奏している形跡は無く、ネットにも全く情報が見当たらない
現在でも演奏をされているのか、はたまたご存命なのか全く分からなかった
しかし、先日遂に大由彰さんの近況を知ることができた
大由彰さんとトリオを組まれていた山本剛さんのライブに行った際に、
山本さんに大由彰さんの近況を質問してみたのだ
「大由彰さんは現在でも演奏をなされているのですか。そもそもご存命なのでしょうか」
「大由彰さんね。生きてるよ、だけど今はもうね演奏してないのよ」
「えっ、どうしてなんですか」
「脳を一回やっちゃってね。彼の演奏凄いでしょ。演奏してると興奮しちゃうの。それでまた脳をやるのが怖いからって止めちゃったのよ…」
「そういうことなんですか…」
ということらしい
現在は演奏を行っていないことは残念だったが、何よりも命あっての人生しょうがない
しかし、今も演奏をなされていたらきっと日本を代表するトッププレーヤーとして名を馳せていたのだろうなぁ
■
Javaプログラマーなら習得しておきたい Java SE 8 実践プログラミング
を読んでいて、BitSet.valueOfの使い方が良くわからなかったので調べた(正確には知ってる人に質問した)
上記書籍の良くわからなかった箇所は下記の部分
BitSet.valueOf(bytes).get(n) == ((bytes[n/8]) & (1<<(n%8))) !=0)
byte[] bytes = {(byte) 0b10101100, (byte) 0b00101000}
BitSet prime = BitSet.valueOf(bytes)
// {2, 3, 5, 7, 11, 13}
一体何がどーなって2, 3, 5, 7, 11, 13なんて数字が出てきたんだ…
valueOf
public static BitSet valueOf(byte[] bytes)
より正確には、
すべての n < 8 * bytes.length
に対してBitSet.valueOf(bytes).get(n) == ((bytes[n/8] & (1<<(n%8))) != 0)
となります。
このメソッドは、BitSet.valueOf(ByteBuffer.wrap(bytes))
と同等です。
一見ややこしいが、javadocの定義によると
1 0 (n / 8)
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 (n%8)
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ( n )
0 0 1 0 1 0 0 0 | 1 0 1 0 1 1 0 0
n = 2の場合
1 = 00000001をn%8だけ左シフトすると00000100
byte[0] = 10101100
つまりこれらのビットのANDは
00000100
10101100
------------
00000100 != 00000000 (0)
BitSet.valueOf(bytes).get(2) == true
となり、2ビット目が立っていることが分かる。
単に、byte配列の値をベースにBitSetを初期化しているだけなんですね。