Null Safetyな言語 Kotlin と Swift を比較
Objective-Cの代替えとしてアップルで生まれたプログラミング言語 Swift と Javaや PHPなどの統合開発環境(IDE)を作っている JetBrainsで生まれたプログラミング言語 Kotlin比較してみます。
Swiftは iOSやmacOS、Kotlinは Android の開発用言語として利用されています。今どきのプログラミング言語の特徴である、Null Safety、クロージャ、継承といった機能を持っています。
基本
いつのもメッセージ
Swift |
Kotlin |
print("Hello, world!") |
println("Hello, world!") |
定数と変数
Swift |
Kotlin |
let myConstant = 36 var myVariable = 36 myVariable = 43 |
val myConstant = 36 var myVariable = 36 myVariable = 43 |
明示的に型を指定
Swift |
Kotlin |
let explicitDouble: Double = 63.8 |
val explicitDouble: Double = 63.8 |
型変換
Swift |
Kotlin |
let label = "幅 " let width = 120 let widthLabel = label + String(width) |
val label = "幅 " val width = 120 val widthLabel = label + width |
let cars = 3 let ships = 4 let vehicle = "乗り物 \(cars+ships) " + "台" |
val cars = 3 val ships = 4 val vehicle = "乗り物 ${cars+ships} " + "台" |
制御
Swift |
Kotlin |
if score > 75 { println("よくできました") } else { println("がんばりましょう") } |
if (score > 75) { println("よくできました") } else { println("がんばりましょう") } |
for item in array { print(item) } |
for (item in array) { println(item) } |
for i in 1..<5 { print(i) } |
for (i in 1..4) { println(i) } |
while num < total { } |
while (num < total) { } |
switch numberSymbol { case "一": print("いち") case "二": print("に") case "三": print("さん") default: print("いくつ?") } |
when (numberSymbol) { "一" -> println("いち") "二" -> println("に") "三" -> println("さん") else -> { println("いくつ?") } } |
Null Safety (Type safe)
Optional と Nullable
Swift |
Kotlin |
var name: String? |
var name: String? |
if let aName = name { print("name is \(aName.count) chars") } else { print("name is nil") } |
if (name != null) { println("name is %d chars".format(name.length)) } else { println("name is null") } |
let count = name?.count |
val length = name?.length |
let aName = name ?? "Swift" |
val aName = name ?: "Kotlin" |
let count = name!.count |
val length = name!!.length |
Collections
Arrays
Swift |
Kotlin |
var shoppingList = [ "おにぎり", "お茶", "チョコレート", "エクレア" ] shoppingList[1] = "紅茶" |
val shoppingList = arrayOf( "おにぎり", "お茶", "チョコレート", "エクレア" ) shoppingList[1] = "紅茶" |
Maps
Swift |
Kotlin |
var os = [ "Mac OS X": "Apple", "Windows": "Microsoft" ] os["Solaris"] = "Sun" |
val os = mutableMapOf( "Mac OS X" to "Apple", "Windows" to "Microsoft" ) os("Solaris") = "Sun" |
空
Swift |
Kotlin |
let emptyArray = [String]() let emptyDictionary = [String: Float]() |
val emptyArray = arrayOf |
関数
関数
Swift |
Kotlin |
func yourName(given: String, family: String) -> String { return "\(family)家の \(given)" } yourName("太郎", "桃宮") |
fun yourName(given: String, family: String): String { return "${family}家の $given" } yourName("太郎", "桃宮") |
タプルを返す関数
Swift |
Kotlin |
func getPrices() -> (Double, Double, Double) { return (12.74, 3.85, 9.17) } |
data class Prices(val a: Double, val b: Double, val c: Double) fun getPrices() = Prices(12.74, 3.85, 9.17) |
可変引数
Swift |
Kotlin |
func sumOf(_ numbers: Int...) -> Int { var sum = 0 for number in numbers { sum += number } return sum } sumOf(36, 138, 65, 11) |
fun sumOf(vararg numbers: Int): Int { var sum = 0 for (number in numbers) { sum += number } return sum } sumOf(36, 138, 65, 11) |
デフォルト引数
Swift |
Kotlin |
func join(str1: String, str2: String, joiner: String = " ") -> String { return str1 + joiner + str2 } |
fun join(str1: String, str2: String, joiner: String = " "): String { return str1 + joiner + str2 } |
名前付き引数
Swift |
Kotlin |
func area(width: Double, height: Double) -> Double { return width * height } area(width: 120, height: 80) |
fun area(width: Double, height: Double) = width * height area(width = 120, height = 80) |
関数型
Swift |
Kotlin |
func makeIncrementer() -> (Int -> Int) { func addOne(number: Int) -> Int { return number + 1 } return addOne } let increment = makeIncrementer() increment(7) |
fun makeIncrementer(): (Int) -> Int { val addOne = fun(number: Int): Int { return number + 1 } return addOne } val increment = makeIncrementer() increment(7) |
Map
Swift |
Kotlin |
let numbers = [18, 14, 7, 25] numbers.map { 2 * $0 } |
val numbers = listOf(18, 14, 7, 25) numbers.map { 2 * it } |
Sort
Swift |
Kotlin |
var mutArray = [1, 11, 5, 3, 7, 2] mutArray.sort() |
listOf(1, 11, 5, 3, 7, 2).sorted() |
クラス
クラス定義
Swift |
Kotlin |
class Shape { var numberOfSides = 0 func feature() -> String { return "辺の数:\(numberOfSides)" } } |
class Shape { var numberOfSides = 0 fun feature() = "辺の数:$numberOfSides" } |
インスタンス
Swift |
Kotlin |
var shape = Shape() shape.numberOfSides = 5 var shapeDescription = shape.feature() |
var shape = Shape() shape.numberOfSides = 5 var shapeDescription = shape.feature() |
継承
Swift |
Kotlin |
class ShapeBase { var numberOfSides: Int = 0 let name: String init(name: String) { self.name = name } func feature() -> String { return "辺の数:\(numberOfSides)" } } class Square: ShapeBase { var sideLength: Double init(sideLength: Double, name: String) { super.init(name: name) self.sideLength = sideLength self.numberOfSides = 4 } func area() -> Double { return sideLength * sideLength } override func feature() -> String { return "\(name)の辺の数:\(numberOfSides)" } } let rectangle = Square(sideLength: 16.2, name: "正方形") rectangle.area() rectangle.feature() |
open class ShapeBase(val name: String) { var numberOfSides = 0 open fun feature() = "辺の数: $numberOfSides." } class Square(var sideLength: BigDecimal, name: String) : ShapeBase(name) { init { numberOfSides = 4 } fun area() = sideLength.pow(2) override fun feature() = "${name}の辺の数:$sideLength" } val rectangle = Square(BigDecimal("16.2"), "正方形") rectangle.area() rectangle.feature() |
型チェック
Swift |
Kotlin |
var carCount = 0 var shipCount = 0 for item in vehicle { if item is Car { carCount += 1 } else if item is Ship { shipCount += 1 } } |
var carCount = 0 var shipCount = 0 for (item in vehicle) { if (item is Car) { carCount++ } else if (item is Ship) { shipCount++ } } |
キャスト
Swift |
Kotlin |
for vehicle in Vehicle { if let car = vehicle as? Car { print("種類: \(car.type)") } } |
for (vehicle in Vehicle) { if (vehicle is Car) { print("種類: ${vehicle.type}") } } |
Protocol / Interface
Swift |
Kotlin |
protocol Nameable { func name() -> String } func f<T: Nameable>(x: T) { print("名前: " + x.name()) } |
interface Nameable { fun name(): String } fun f<T: Nameable>(x: T) { println("名前: " + x.name()) } |
Extensions
Swift |
Kotlin |
extension Double { var km: Double { return self * 1_000.0 } var m: Double { return self } var cm: Double { return self / 100.0 } var mm: Double { return self / 1_000.0 } var ft: Double { return self / 3.28 } } let oneInch = 2.54.cm print("1インチ = \(oneInch) メートル") let twoFeet = 2.ft print("2フィート = \(twoFeet) メートル") |
val Double.km: Double get() = this * 1000 val Double.m: Double get() = this val Double.cm: Double get() = this / 100 val Double.mm: Double get() = this / 1000 val Double.ft: Double get() = this / 3.28 val oneInch = 2.54.cm println("1インチ = $oneInch メートル") val twoFeet = 2.0.ft println("2フィート = $twoFeet メートル") |