Posted at

ずっとオブジェクト指向の言語しか触ってこなかった人がSwiftに出会って痺れたこと

More than 1 year has passed since last update.


ずっとオブジェクト指向

ずっとオブジェクト指向型言語ばっかやってきたんですが、Swiftに出会ってその方法もあったか、みたいな発見がいくつかあったので紹介しようと思います。


Swift

Swiftはオブジェクト指向型言語です。でも、関数型言語やプロトコル型言語とも呼ばれます。一見すると全くコンテキストの異なるセグメントに見えますが、各々の言語の弱点を柔軟に解決すべく、ざまざまなパラダイムを取り込んだ言語、それがSwiftです。


そもそもポインタがない

C++やObjective-Cをやってきた人にとっては慣れないかもしれません。

一方、Javaをやってきた人には馴染みある特徴です。

しかし、参照か値で渡されるのを決めるのはどのようにして決められるのでしょうか。

class/structでは、それぞれが参照なのか値なのか区別されます。

継承ができるのもclassだけです。


Enumがめっちゃ拡張できる

これかなり痺れました。

自由にメソッドはやせるし、mutatingなメソッド(自分自身を変える破壊的なメソッド)も定義できるのです。

 enum Color: String {

case red,
case green,
case blue
mutating changeNextColor() {
switch self {
case .red:
self = .green
case .green:
self = .blue
case .blue:
self = .red
}
}
}


なにが嬉しいのか


オブジェクト指向の問題点は、適切なデータに付随する責任関係を[継承か集約]でしか表現できないことでした。適切なデータと適切な処理を適切な"場所"に。

データ x 処理における、この適材適所を実現可能にしているのがこの柔軟なデータ設計の考え方だとも言えます。


関数型言語

Swiftが関数型言語とも呼ばれる所以は関数を第一級オブジェクト、言い換えれば、ほかの変数と同じように「オブジェクト」として扱えるところにあります。

関数型の考え方は、あるインプットに関してアウトプットが必ず同じでなければなかったり、状態を持たないなどのいくつかの制約があります。

便利なのは先述した「関数をオブジェクト」として扱えることにあります。

例えばこんな定義の仕方ができます


typealias Region = (Point)->Bool

地域とは、ある座標を与えられたときにそのうちにあるかどうかを判断するためのものです。(少し抽象的な説明ですね)

要するに、データとデータの関係性自体をオブジェクト化できる簡潔さが魅力だと思います。

これを基調とした考え方を学ぶにはfunctional swiftという本がおすすめです。


プロトコル指向

プロトコルという考え方自体はC++やObjective-C/Javaにもあります。それぞれの呼び方は異なりますが(Javaだとインターフェイスと呼ばれたり)、オブジェクト指向とは異なり、メソッドのオーバーライドが必要なかったりコードをまとめやすいなどの特徴があります。抽象化の面倒なものに引きずられるというリスクを取り除くことができます。


protcol Animal {
var name : String { get }
var residence : String { get }
}

struct Dog: Animal {
var name:String {
return "Dog"
}

var residence:String {
return "Home"
}
}

この考え方は2015年のWWDCの講演であるProtocol Oriented Language Swiftがおすすめです。


マルチパラダイムであること

このように、Swiftという言語は、あらゆるパラダイムの弱点を、複数のパラダイムによって回避でき、かつシンプルに書くことのできる柔軟さと強さを兼ね備えた言語であることが理解できます。

しかし裏返しとして、これはほかの言語をやってきた人がみて凄みを理解できるものの、Swiftからやり始めた人がほかの言語に行くときに苦しくなるであろう点でもありそうです。