LoginSignup
40
28

More than 5 years have passed since last update.

iOSエンジニアのAndroidアプリ開発備忘録 - Swift、Kotlinの構文比較編

Last updated at Posted at 2016-10-02

iOSエンジニアがAndroidアプリ開発時の備忘録 - Swift、Kotlinの構文比較編.png

本記事の前段についてはこちら
iOSエンジニアのAndroidアプリ開発備忘録 - Qiita

対象読者

備忘録のため、主に自分。
もしくは、iOSアプリを開発(Swift)やってた人で、Kotlin触ってみたいなって人。

本題

Swift やってればだいたい分かるけど、ちょくちょく文法の違いはある。
とりあえずリファレンス読んでおけば事足ります。
僕が開発したての頃とくに「どうやって書くんだっけ?」ってなったところを列挙します。

Playground

まずは触ってみたいと思う人が多いだろうと思う。(僕がそうだったから)
swiftの Playground 相当のものは Kotlin にはないため REPL を使っていた。

  • Android Studio(+ Kotlin Plugin)が入っている場合
    • FindAction(⌘ + ⇧ + A)から Kotlin REPL を選択
  • ターミナルからの場合
    • brew install kotlin で 入れれば試せる。詳細のインストール方法等はこちら
    • Android Studio も内部ではコマンど叩いてるだけだけだと思う

constant, variable

定数、変数の宣言。超初歩的だけど、「初めアレ?」ってなったので。

Swift Kotlin
constant let val
variable var var

if let

let または run を使用する。

Swift
var str: String? = "Hello, Swift"
print(str) // "Optional("Hello, Swift")"
print(str!) // "Hello, Swift"
if let str = str {
    print(str) // "Hello, Swift"
} else {
    print("str is nil")
}
Kotlin
var str: String? = "Hello, Kotlin"
print(str) // "Hello, Kotlin"
print(str!!) // "Hello, Kotlin"
str?.let {
    print(it) // "Hello, Kotlin"
} ?: run {
    print("str1 is null")
}

Forced Unwrapping

Kotlin ではエクスクラメーションマーク1つではなく、2つ !!

Swift
var str: String? = nil
print(str) // nil
print(str!) // "fatal error: unexpectedly found nil while unwrapping an Optional value"
Kotlin
var str: String? = null
print(str) // "null"
print(str!!) // "kotlin.KotlinNullPointerException"

暗黙的アンラップ・Implicitly Unwrapped Optional

等価って考えていいのかな。Late-Initialized Propertiesってのがあります。
(Force Unwrapping した時との例外メッセージが違うので等価ではなさそう。KotlinNullPointerExceptionUninitializedPropertyAccessException

Swift
class MyClass {
    var foo: String!
    var bar: String!
}
val myClass = MyClass()
myClass.foo = "foo"
print(myClass.foo)
print(myClass.bar) // "fatal error: unexpectedly found nil while unwrapping an Optional value"
Kotlin
class MyClass {
    lateinit var foo: String
    lateinit var bar: String
}
val myClass = MyClass()
myClass.foo = "foo"
print(myClass.foo)
print(myClass.bar) // kotlin.UninitializedPropertyAccessException: lateinit property bar has not been initialized

guard

Swift
func foo(str: String?) {
    guard let str = str else {
        print("str is null")
        return
    }
    print(str.characters.count) // "4"
}

foo(str: "hoge")
Kotlin
fun foo1(str: String?) {
    if (str == null) {
        print("str is null")
        return
    }
    print(str.length) // "4"。 unwrap しなくて良い。賢い
}
foo1("hoge")

// もしくは、こんな書き方
fun foo2(str: String?) {
    var str = str ?: return
    print(str.length) // "4"
}
foo2("hoge")

Switch

when だよ。

Swift
let x = 1
switch x {
    case 1: print("x == 1")
    case 2: print("x == 2")
    default: print("x is neither 1 nor 2")
}
Kotlin
val x = 1
when (x) {
  1 -> print("x == 1")
  2 -> print("x == 2")
  else -> print("x is neither 1 nor 2")
}

三項演算子・Tertiary Operator

ちゃんと if else 書こう。

Swift
let a  = 1
let b  = 2
let result = a > b ? "foo" : "bar"
print(result) // "bar"
Kotlin
val a  = 1
val b  = 2
val result = if(a > b) "foo" else "bar"
print(result) // "bar"

構造体・Struct

classdata 修飾子をつける

Swift
struct Resolution { var width: Int, height: Int }
let r = Resolution(width: 1, height: 2)
print(r) // "Resolution(width: 1, height: 2)"
Kotlin
data class Resolution(val width: Int, val height: Int){}
val r = Resolution(1, 2)
print(r) // "Resolution(width: 1, height: 2)"

拡張・Extension

  • プロパティーの拡張
Swift
extension Double {
    var km: Double { return self * 1_000.0 }
    var m: Double { return self }
    var cm: Double { return self / 100.0 }
}
print(25.4.km)
Kotlin
val Double.km: Double get() = this * 1000.0
val Double.m: Double get() = this
val Double.cm: Double get() = this / 100.0
print(25.4.km)
  • メソッドの拡張
Swift
extension Int {
    func repetitions(task: () -> ()) {
        for _ in 0..<self {
            task()
        }
    }
}

3.repetitions {
    print("Hello, Swift!")
}
// "Hello, Swift!"
// "Hello, Swift!"
// "Hello, Swift!"
Kotlin
fun Int.repetitions(task: () -> Unit) {
    for (i in 0 until this) {
        task()
    }
}

3.repetitions {
    println("Hello, Kotlin!")
}
// "Hello, Kotlin!"
// "Hello, Kotlin!"
// "Hello, Kotlin!"

静的・Static

companion object ってのを使う。未だにピンとこない

Swift
class MyClass {
    static func foo() -> String {
        return "Hello, Swift!"
    }
    static let bar = "Hello, Swift!"
}
print(MyClass.foo()) // "Hello, Swift!"
print(MyClass.bar) // "Hello, Swift!"
Kotlin
class MyClass {
    companion object {
        fun foo() {
            print("Hello, Kotlin!")
        }
        val bar = "Hello, Kotlin!"
    }
}
print(MyClass.foo()) // "Hello, Kotlin!"
print(MyClass.bar) // "Hello, Kotlin!"

タプル

Kotlinにはない。Pairならある。2つだけ。非常に悲しい

Swift
let foo = ("left", "right")
print(foo.0) // "left"
print(foo.1) // "right"
Kotlin
val foo = Pair("left", "right")
print(foo.first) // "left"
print(foo.second) // "right"

with, let, apply, run

上記でも紹介したが let 以外に with, let, apply, run などの構文がある。
Swiftにはない構文で比較というわけではないので詳細は省きますが便利です。
詳しくはこちら

遅延評価

Swift
class MyClass {
    lazy var foo = "foo"
}
Kotlin
class MyClass {
    val foo: String by lazy { "foo" }
}

まとめ

他にも annotation や、sealed class などなど紹介しきれていない構文がありますが、また改めて。

まだまだKotlinを始めて数カ月ではありますが、少しでも同じような立場の人の手助けになればと思い書きました。また、何か僕の理解の不十分な箇所や誤りなどあったらご指摘いただけると幸いです。

続きは、Xcode、Android Studio 比較編

40
28
0

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
40
28