golangでのstringへのアクセス

golangでstringへとindex or rangeでアクセスした時の型とindexと数値を調べた

package main

import (
    "fmt"
)

func main() {
    s := "hello 日本語"
    fmt.Println("index, access")
    for i := 0; i < len(s); i++ {
        fmt.Printf("%T ", s[i])
        fmt.Println(i, s[i], string(s[i]))
    }
    fmt.Println("\nrange access")
    for i, v := range s {
        fmt.Printf("%T ", v)
        fmt.Println(i, v, string(v))
    }
    fmt.Println("\nちなchrっぽいアレ")
    c := 'A'
    fmt.Printf("%T ", c)
    fmt.Println(c, string(c))
}

これが

index, access
uint8 0 104 h
uint8 1 101 e
uint8 2 108 l
uint8 3 108 l
uint8 4 111 o
uint8 5 32  
uint8 6 230 æ
uint8 7 151 
uint8 8 165 ¥
uint8 9 230 æ
uint8 10 156 
uint8 11 172 ¬
uint8 12 232 è
uint8 13 170 ª
uint8 14 158 

range access
int32 0 104 h
int32 1 101 e
int32 2 108 l
int32 3 108 l
int32 4 111 o
int32 5 32  
int32 6 26085 日
int32 9 26412 本
int32 12 35486 語

ちなchrっぽいアレ
int32 65 A

こうなる。

stringへindex accessするとuint8型と扱われる。当然ascii以外の文字はぶっ壊れる

stringへrange accessすると、ascii文字を含めてint32として扱われる。ascii以外の文字を読み込んだ時はちゃんとindexも多めにずれる。ワザマエ

おまけとして、unicode/utf8にRuneStart(b byte) boolっていう与えられたbyteからunicode文字列が始まれるか教えてくれる関数があって、こいつとindex accessを組み合わせればrangeみたいなこともできるっぽい。

Windowsでeasy_install

Windowsでsetup toolsをインストールするのがeasyすぎるっていう話

https://pypi.python.org/pypi/setuptools

に書いてある通りなんだけど、powershellでおまじないを唱えるか、pythonインタープリタにPATHを通した上で落としてきたez_setup.pyを実行するだけでeasy_install.exeが出来上がる。思ってたよりずっと簡単。

後はeasy_install.exenoをPATHにぶっこめば、easy_install {入れたいモジュール名}するだけモジュールをインストールできる

補足1

python moduleの中にはCで書かれたコードによって高速化を図っているものが結構ある。

全てのmoduleがWindows用のバイナリを用意してくれている訳ではないので、http://www.mingw.org/のようなCをビルドする環境が必要になるかもしれない。

補足2

scipyとかscikit-learnとかのライブラリが必要とするCやFortranのライブラリのビルドは素人が手を出すにはハードルが高く感じるので、大人しくWindows用のインストーラを利用するか、潔く諦めたほうが精神衛生上宜しい気がする。

Pythonのforとwhile

whileを見たら殺せと教わったpythonistaですおはこんばんちは。

ベンチマークしたことがこれまでなかったので試して見ました。

timeitモジュール使うの初めてだから間違いがあるかも

ちなPython 2.7.3

Haskellで関数が左結合だということ

print filter f xs

とした時に、なんでエラーが出るかってわけ。

a b c d

と並んでいるものは、関数適用において左結合であるHaskellによれば

((a b) c) d

と解釈される。

よって関数aにbを食わせてcを食わせてdを食わせた結果何かが起こるので、aの型は

a :: b -> c -> d -> e

となる。だから上の例だとエラーが起きる

Haskellでは常にカリー化されていることと、括弧を省略できることで混乱していたけれど、括弧をちゃんとつければまあ多少は、ね?

LinuxでGolangの環境を整えるまで

ソースからGolangを入れて、Vimで編集できるようになるまで

参考

http://golang.jp/install/source

http://mattn.kaoriya.net/software/vim/20130531000559.htm

前提

mercurialとgitとbuild essential的なものとVimは事前にインストールされているとする。

ソースからのビルド

hg clone -u release https://code.google.com/p/go

してソースコードをクローンする

cd go/src
./all.bash

すると現在の環境に応じてビルド・テスト・ベンチマークが自動で行われる

環境変数の設定

export GOROOT=$HOME/go
export GOPATH=$HOME/.golang
export PATH=$GOROOT/bin:$PATH
export PATH=$GOPATH/bin:$PATH

こんな感じのことを~/.bash_profileとか~/.profileとかに書いておく

$GOPATHはgo getで入れたパッケージが保存されるディレクトリ

ココらへんどこに書けばいいのか実は分かっていないし、ついでに環境変数変えた時に一般的にどうするかも分かってないので誰か教えて下しあ。迷ったら再ログインすればいいんだけど

godocを入れる

ドキュメントを読むために入れる

go get code.google.com/p/go.tools/cmd/godoc

エラーが出なければ何事もなくインストールできたってことになる文化らしい。

godoc {package_name}

すると端末上で読める。

godoc -http=:8080

とかするとブラウザーからlocalhost:8080を開くことで読める

gocodeを入れる

入力補完するためのgocodeを入れる。

go get github.com/nsf/gocode

.vimrcの設定

goのシンタックスファイルの読み込み

 set rtp+=$GOROOT/misc/vim 

すればよしなにしてくれる。

また、VimにImportとかFmtとかGodocコマンドが増える。

:Import {package_name}

するとカーソル移動無しにインポートしてくれるし

:Fmt

するとgofmtによってソースコードが自動整形される。

:Godoc {package_name}

するとドキュメントが表示される。

ちなパッケージの名前はwildcharで補完できる。Vimだと既定値は<tab>

gocodeを使用した補完

gocodeに付属するsymlinkを作るシェルスクリプトを使ってもいいけれど、今時のvim環境的に.vim内がごちゃごちゃするのは個人的に好かない。ちなシェルスクリプト$GOPATH/src/github.com/nsf/gocode/vim内にある。

それか、.vimrcに以下の一文を載せる

exe "set rtp+=".globpath($GOPATH, "src/github.com/nsf/gocode/vim")

これで<c-x><c-o>でオムニ補完ができるようになる。

neocomplechacheやらneocompleteやらを使う人は

    if !exists('g:neocomplete#sources#omni#input_patterns')
        let g:neocomplete#sources#omni#input_patterns = {}
    endif
    let g:neocomplete#sources#omni#input_patterns.go = '[^.[:digit:] *\t]\.\w*'

とか

    if !exists('g:neocomplete#sources#omni#input_patterns')
        let g:neocomplete#sources#omni#input_patterns = {}
    endif
    let g:neocomplete#sources#omni#input_patterns.go = '[^.[:digit:] *\t]\.\w*'

する感じ?

設定例

ネオコンの設定を除いた今使ってる設定がこれ

" golang
    set rtp+=$GOROOT/misc/vim
    exe "set rtp+=".globpath($GOPATH, "src/github.com/nsf/gocode/vim")
    auto BufWritePre *.go Fmt
    autocmd FileType go nnoremap <buffer> <F5> :call <SID>compileGo()<CR>
    autocmd FileType go nnoremap <buffer> <F6> :call <SID>runGo()<CR>
    autocmd FileType go nnoremap <buffer> <F7> :call <SID>runGoToFile()<CR>
    function! s:compileGo()
        :w
        exe ':lcd %:p:h'
        exe ":!go build %"
    endfunction

    function! s:runGo()
        exe ':!./%:r'
    endfunction

    function! s:runGoToFile()
        exe ":!%:r > %.data"
    endfunction