ちょっと話題の記事

Java/C++プログラマのためのSwiftチートシート

2014.11.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Java/C++プログラマーのためのSwiftチートシートです。
現在の内容は 2014/11/27 のものです。項目は適宜追加される可能性があります。

概要

むかしむかし、この地球には「ぼくはJava(C++)を愛しているから、どうしてもObjective-Cを書く気にならない。だからぼくは、iOS開発しないんだ」というおじさんがたくさんいました。

私達にとって、Swiftは朗報でした。しかし、C++/JavaベースでSwiftを説明しているリファレンスは、現状そんなに多くありません(少なくとも、Objective-Cベースのリファレンスに比べれば)。そんなわけで、基本的な部分のみですが、差分をまとめましたので、ご活用ください。

バージョン情報

本記事は、下記のバージョンについて記述しています。

言語 バージョン
Java SE 6
C++ ISO/IEC 14882:2011
Swift 1.0

また、各言語とも、自明の前置きについては省略しています。(#include <iostream>, import Foundation, etc...)

変数の定義と初期化

Java C++ Swift
int i = 0; int i = 0; var i : Int = 0
final int K = 127; const int K = 127; let K : Int = 127
CHoge hoge = new CHoge(); CHoge* hoge = new CHoge;
...
delete hoge;
var hoge : CHoge = CHoge()
final CHoge hoge = new CHoge(); CHoge* const hoge = new CHoge;
...
delete hoge;
let hoge : CHoge = CHoge()
該当なし const CHoge* hoge = new CHoge;
...
delete hoge;
該当なし
該当なし auto num = 1; var num = 1
該当なし const auto num = 1; let num = 1
該当なし auto hoge = new CHoge; var hoge = CHoge()
該当なし auto const hoge = new CHoge; let hoge = CHoge()
int[] arr = new int[5]; int arr[5]; 該当なし
ArrayList<Integer> arr
    = new ArrayList<Interger>();
std::vector<int> arr(); var arr : [Int] = [Int]()

クラス・メンバ・メンバ関数の定義

Java

class Person {
    private String name;
    public Person(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name;
    }
    public String getCombinedName(Person p) {
        return this.name + " with " + p.getName();
    }
}

C++

class Person {
private:
    const char* name;
public:
    Person(const char *);
    const char* GetName();
    const char* GetCombinedName(Person &);
};

Person::Person(const char* name) {
    this->name = name;
}
const char* Person::GetName() {
    return this->name;
}
const char* Person::GetCombinedName(Person &p) {
    return (std::string(this->name) + " with " + p.GetName()).c_str();
}

Swift

class Person {
    let name : String // variables declared by 'let' have a read-only policy
    init(name : String) {
        self.name = name
    }
    func getCombinedName(h: Person) -> String {
        return self.name + " with " + h.name;
    }
}

クロージャ

Java

interface Function<T> {
    public T invoke();
}
class Wrapper<T> {
    public T value;
    public Wrapper(T value) {
        this.value = value;
    }
}
class ClosureTest {
    public static Function<Integer> createSequenceClosure() {
        final Wrapper<Integer> count = new Wrapper(new Integer(0));
        return new Function<Integer>() {
            public Integer invoke() {
                return ++count.value;
            }
        };
    }
    public static void main (String[] args) {
        Function<Integer> seqA = createSequenceClosure();
        System.out.println("seqA:" + seqA.invoke());
        // -> seqA:1
        Function<Integer> seqB = createSequenceClosure();
        System.out.println("seqA:" + seqA.invoke() + " seqB:" + seqB.invoke());
        // -> seqA:2 seqB:1
    }
}

C++

int main() {
    auto CreateSequenceClosure = []() {
        int count = 0;
        return [&]() { return ++count; };
    };
    auto SeqA = CreateSequenceClosure();
    std::cout << "SeqA:" << SeqA() << std::endl;
    // -> SeqA:1
    auto SeqB = CreateSequenceClosure();
    std::cout << "SeqA:" << SeqA() << " SeqB:" << SeqB() << std::endl;
    // -> SeqA:2 SeqB:1
}

Swift

let createSequence = { () -> () -> Int in
    var count = 0
    return { return ++count }
}
let seqA = createSequence()
println("seqA:\(seqA())")
// -> seqA:1
let seqB = createSequence()
println("seqA:\(seqA()) seqB:\(seqB())")
// -> seqA:2 seqB:1

補足

  • Javaは、Androidで使用されているJava SE 6で記述したので、他と比べ冗長になっています。Java SE 8ならもっと戦えます(たぶん)。
  • Java/C++と異なり、Swiftは関数型プログラミングを強くサポートしています。がっつり使っていく場合は、あまりJava/C++のプラクティスを流用すべきではないかもしれません。