こんばんはささおです
SwiftとKotlinって書き方が似ているところと、
どちらもモバイルアプリを中心に使用されているせいか
よく比較されますよね〜
そこで今回はGenericsについてです!
Kotlinではできるけど、SwiftにはできないGenericsの機能についてを書いていきます!
それでは書いていきましょう!!
できる(Kotlin)
『AnimalBoxというTという型パラメータを使用しているクラス』と
『Animalというベースになっているクラス』と
『CatというAnimalを継承しているクラス』を定義しています。
fun main(args: Array<String>){ var animalBox: AnimalBox<Animal> = AnimalBox<Animal>() animalBox = AnimalBox<Cat>() } class AnimalBox<out T> {} open class Animal {} class Cat: Animal() {}
で、何が言いたいの??
注目すべきはここです!
var animalBox: AnimalBox<Animal> = AnimalBox<Animal>() animalBox = AnimalBox<Cat>()
animalBoxという変数を定義する際に
『型パラメータにAnimalを指定したAnimalBoxのインスタンス』を格納してます。
さらに次の行!!
その『animalBox変数』に
『型パラメータにCatを指定したAnimalBoxのインスタンス』を代入しています!
CatはAnimalの子クラスです。普通にできそうですが、Swiftにはできない機能です。
これを『共変』といいます。
共変させるにはクラスを定義するときの型パラメータの前に『out』をつけてあげる必要があります。
class AnimalBox<out T> {}
これがKotlinにできてSwiftにできないことです!
できない(Swift)
Swiftではできないわけですが、一応やってみます。
class AnimalBox<T> {} class Animal {} class Cat: Animal {} var animalBox = AnimalBox<Animal>() animalBox = AnimalBox<Cat>() // Cannot assign value of type 'AnimalBox<Cat>' to type 'AnimalBox<Animal>'
Cannot assign value of type ‘AnimalBox<Cat>’ to type ‘AnimalBox<Animal>’と言われてしまいます・・・
『AnimalBox<Animal>の型にAnimalBox<Cat>のインスタンスを代入をすることはできないよ!』ってな感じですね。
やっぱりできませんね・・・
Swiftでは共変性がないの??
う〜んあるにはあるっぽいんですよ・・・
なんとArrayやOptionalは共変します・・・!
class Animal {} class Cat: Animal {} var animalArray = Array<Animal>() animalArray = Array<Cat>() // できる!!
できちゃいますね〜
難しいですね〜