LoginSignup
16
13

More than 5 years have passed since last update.

GoとSwiftを比較して使いやすかったとこと使いにくかったところのまとめ

Posted at

仙台iOS開発者勉強会(SWWDC) Advent Calendar 2014の22日目の記事です。

新しい言語を覚えるときによく作るのがWhiteSpaceのインタプリタです。以前は、ネットに上がっている問題やProject Eulerの問題を解いていたのですが、どうせだったら、作り終わったあとも使えるものはないかと思い、作り始めました。
WhiteSpaceの解説は、Wiki公式るびまを参考にして戴けると解りやすいと思います。

今回は、GoとSwiftでWhitespaceのインタプリタを作って言語により、作りやすかった点と難しかった点を2つにまとめてみました。

実際に作成したコードはこちら

文字列フィルタリング

whitespaceで有効な文字は、" "(半角スペース)、"\t"(タブ)、"\n"(改行)の3つです。

Goでは、オリジナルのデータを1byteずつ読み込み有効な3つの文字だったときは、新しい文字のスライス(配列)に保存する方法ととりました。
Swiftでは、filterメソッドを利用することで同じように有効な3つの文字を抽出できます。
個人的には、Swiftのfilterメソッドが使いやすく読みやすかったなと思いました。

interprinter.go
func (inter *Interpreter) filter() {
    for _, b := range inter.origin {
        if bytes.IndexByte([]byte{Space, Tab, Lf}, b) >= 0 {
            inter.source = append(inter.source, b)
        }
    }
}
CodeStack.swift
init(code: [Character]) {
    self.code = code.filter({
        (c: Character) -> Bool in
        return c == " " || c == "\t" || c == "\n"
    })
}

配列(スライス)から任意文字数の取得

[Space]のStack操作命令や[Tab][Space]の計算処理のようにWhiteSpaceでは、使用する命令によって文字数が異なります。
Goで実装したときとSwiftで実装したときでは、実装方法が異なっているのですが、配列(スライス)から任意の文字数を取得する仕組みに差があったので、実装方法を別にしました。

Goの方は、添字に[n:m]を使って必要なデータを取得します。nは、取得する最初の位置、mが最後の位置です。
同じようにSwiftで実装しようと思ったのですが、方法が見つからず結果、switch case で実装していまいました。

converter.go
func arithmetic(data []byte) (*Command, int, error) {
    cmd := data[0:2]
    switch {
    case bytes.Compare(cmd, []byte{Space, Space}) == 0:
        return newCommand("add"), len(cmd), nil
    case bytes.Compare(cmd, []byte{Space, Tab}) == 0:
        return newCommand("sub"), len(cmd), nil
    case bytes.Compare(cmd, []byte{Space, Lf}) == 0:
        return newCommand("mul"), len(cmd), nil
    case bytes.Compare(cmd, []byte{Tab, Space}) == 0:
        return newCommand("div"), len(cmd), nil
    case bytes.Compare(cmd, []byte{Tab, Tab}) == 0:
        return newCommand("mod"), len(cmd), nil
    }
    return nil, 0, fmt.Errorf("not defined command [%s]", "arithmetic")
}
Wspace.swift
func run() {
    for c in code {
        switch c {
        case " ":
            stackFunc()
            break
        case "\n":
            flowControl()
            break
        case "\t":
            switch code.advance()! {
            case " ":
                calcFunc()
                break
            case "\t":
                heapFunc()
                break
            case "\n":
                consoleFunc()
                break
            default:
                println("error: not found command")
                return
            }
            break
        default:
            println("error: not found command")
            return
        }
    }
}

switch文が多くなってしまったので、今後改善するとすれば、switch文を使わない実装に変更していきたいと考えています。

最後に

iOSに関連して Swift を使ってどんな実装方法があるのかGOと比較してみました。
GOも1.4になってAndroidに対応したようで、今後は、Goを使ってAndroidやサーバーアプリを、Swiftを使ってiOSアプリを実装していければよいなと思った2014年の年でした。
クリスマスまであと3日風邪にお気をつけて元気にお過ごしください!

16
13
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
13