Swift と Scalaって似てない?
アップルのiOSおよびOS Xのためのプログラミング言語 Swift と オブジェクト指向言語と関数型言語の特徴を統合したプログラミング言語 Scala がとても 似ているのでちょっと比較してみます。比較だけしているので、それぞれの細かい言語仕様は各サイトで確認して下さい。
Scala は、もっと簡単な(省略した)記述ができますが、Swiftとの比較を分かりやすくするためにちょっと冗長な記述にしています。
※ 初期のバージョンのSwiftをもとに記述しています。最新のバージョンの Swiftでは、一部記述方法が変更されています。
基本
いつのもメッセージ
Swift |
Scala |
println("Hello, world!") |
println("Hello, world!") |
定数と変数
Swift |
Scala |
let myConstant = 36 var myVariable = 36 myVariable = 43 |
val myConstant = 36 var myVariable = 36 myVariable = 43 |
明示的に型を指定
Swift |
Scala |
let explicitDouble: Double = 63.8 |
val explicitDouble: Double = 63.8 |
型変換
Swift |
Scala |
let label = "幅 " let width = 120 let widthLabel = label + String(width) |
val label = "幅 " val width = 120 val widthLabel = label + width |
制御
Swift |
Scala |
if score > 75 { println("よくできました") } else { println("がんばりましょう") } |
if (score > 75) { println("よくできました") } else { println("がんばりましょう") } |
for var index = 0; i < 3; ++index { println("index = \(index)") } |
ありません |
ありません |
for (i <- 1 to 5) yield i^2 |
while num < total { } |
while (num < total) { } |
switch numberSymbol { case "一": println("いち") case "二": println("に") case "三": println("さん") default: println("いくつ?") } |
numberSymbol match { case "一" => println("いち") case "二" => println("に") case "三" => println("さん") case _ => println("いくつ?") } |
インクリメンタル・ループ
Swift |
Scala |
let seasons = ["春", "夏", "秋", "冬"] let count = seasons.count for i in 0..count { println("\(seasons[i])") } |
val seasons = Array("春", "夏", "秋", "冬") val count = seasons.length for (i <- 0 until count) { println(s"${seasons(i)}") } |
for index in 1...3 { println("\(index) × 5 = \(index * 5)") } // 1 × 5 = 5 // 2 × 5 = 10 // 3 × 5 = 15 |
for (index <- 1 to 3) { println(s"$index × 5 = ${index * 5}") } // 1 × 5 = 5 // 2 × 5 = 10 // 3 × 5 = 15 |
式とCollections
式
Swift |
Scala |
a + b |
a + b |
a = b (a, b) = (1, 2) |
a = b ありません |
a is T |
a.isInstanceOf[T] |
a as T a as? T |
a.asInstanceOf[T] ありません |
"\(x) + \(y) = \(x + y)" |
s"$x + $y = ${x + y}" |
[a, b, c] |
Array(a, b, c) |
[a: b, c: d] |
scala.collection.mutable.Map(a -> b, c -> d) |
self self.foo self[foo] self.init(foo) |
this this.foo this(foo) this(foo) |
super.foo super[foo] super.init(foo) |
super.foo super(foo) ありません |
Arrays
Swift |
Scala |
var shoppingList = [ "おにぎり", "お茶", "チョコレート", "エクレア" ] shoppingList[1] = "紅茶" |
var shoppingList = Array( "おにぎり", "お茶", "チョコレート", "エクレア" ) shoppingList(1) = "紅茶" |
Maps
Swift |
Scala |
var os = [ "Mac OS X": "Apple", "Windows": "Microsoft" ] os["Solaris"] = "Sun" |
var os = scala.collection.mutable.Map( "Mac OS X" -> "Apple", "Windows" -> "Microsoft" ) os("Solaris") = "Sun" |
空
Swift |
Scala |
let emptyArray = String[]() let emptyDictionary = Dictionary |
val emptyArray = Array[String]() val emptyDictionary = Map[String, Float]() val emptyArrayNoType = Array() |
closure
Swift |
Scala |
{ (parameters) -> returnType in ... } |
{ (parameters) => ... } |
placeholders
Swift |
Scala |
f { $0 > $1 } |
f { _ > _ } |
関数
関数
Swift |
Scala |
func yourName(given: String, family: String) -> String { return "\(family)家の \(given)" } yourName("太郎", "桃宮") |
def yourName(given: String, family: String): String = { return s"${family}家の $given" } yourName("太郎", "桃宮") |
タプル
Swift |
Scala |
func getPrices() -> (Double, Double, Double) { return (12.74, 3.85, 9.17) } |
def getPrices(): (Double, Double, Double) = { return (12.74, 3.85, 9.17) } |
可変引数
Swift |
Scala |
func sumOf(numbers: Int...) -> Int { var sum = 0 for number in numbers { sum += number } return sum } sumOf(36, 138, 65, 11) |
def sumOf(numbers: Int*): Int = { var sum = 0 for (number <- numbers) { sum += number } return sum } sumOf(36, 138, 65, 11) |
デフォルト引数
Swift |
Scala |
func join(str1: String, str2: String, joiner: String = " ") -> String { return str1 + joiner + str2 } |
def join(str1: String, str2: String, joiner: String = " "): String = { return str1 + joiner + str2 } |
名前付き引数
Swift |
Scala |
func area(#width: Int, #height: Int) -> Int { return width * height } area(width: 120, height: 80) |
def area(width: Int, height: Int): Int = { return width * height } area(width = 120, height = 80) |
関数型
Swift |
Scala |
func makeIncrementer() -> (Int -> Int) { func addOne(number: Int) -> Int { return 1 + number } return addOne } var increment = makeIncrementer() increment(7) |
def makeIncrementer(): Int => Int = { def addOne(number: Int): Int = { return 1 + number } return addOne } var increment = makeIncrementer() increment(7) |
Map
Swift |
Scala |
var numbers = [18, 14, 7, 25] numbers.map({ number in 2 * number }) |
var numbers = Array(18, 14, 7, 25) numbers.map( number => 2 * number ) |
Sort
Swift |
Scala |
sort([1, 11, 5, 3, 7, 2]) { $0 > $1 } |
Array(1, 11, 5, 3, 7, 2).sortWith(_ > _) |
クラス
クラス定義
Swift |
Scala |
class Shape { var numberOfSides = 0 func simpleDescription() -> String { return "辺の数: \(numberOfSides) " } } |
class Shape { var numberOfSides = 0 def simpleDescription(): String = { return s"辺の数: $numberOfSides" } } |
インスタンス
Swift |
Scala |
var shape = Shape() shape.numberOfSides = 5 var shapeDescription = shape.simpleDescription() |
var shape = new Shape() shape.numberOfSides = 5 var shapeDescription = shape.simpleDescription() |
型チェック
Swift |
Scala |
var carCount = 0 var shipCount = 0 for item in vehicle { if item is Car { ++carCount } else if item is Ship { ++shipCount } } |
var carCount = 0 var shipCount = 0 for (item <- vehicle) { if (item.isInstanceOf[Car]) { carCount += 1 } else if (item.isInstanceOf[Ship]) { shipCount += 1 } } |
パターンマッチ
Swift |
Scala |
var carCount = 0 var shipCount = 0 for item in vehicle { switch item { case let car as Car: ++carCount println("車: '\(car.name)'") case let ship as Ship: ++shipCount println("船: '\(ship.title)'") } } |
var carCount = 0 var shipCount = 0 for (item <- vehicle) { item match { case car: Car => carCount += 1 println(s"車: '${car.name}'") case ship: Ship => shipCount += 1 println(s"船: '${ship.title}'") } } |
キャスト
Swift |
Scala |
for object in someObjects { let vehicle = object as Vehicle println("乗り物: '\(vehicle.name)'") } |
for (obj <- someObjects) { val vehicle = obj.asInstanceOf[Vehicle] println(s"乗り物: '${vehicle.name}'") } |
Protocol
Swift |
Scala |
protocol Nameable { func name() -> String } func f<T: Nameable>(x: T) { println("名前: " + x.name()) } |
trait Nameable { def name(): String } def f[T <: Nameable](x: T) = { println("名前: " + x.name()) } |
Extensions
Swift |
Scala |
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 println("1インチ = \(oneInch) メートル") let twoFeet = 2.ft println("2フィート = \(twoFeet) メートル") |
object Extensions { implicit class DoubleUnit(d: Double) { def km: Double = { return d * 1000.0 } def m: Double = { return d } def cm: Double = { return d / 100.0 } def mm: Double = { return d / 1000.0 } def ft: Double = { return d / 3.28 } } } import Extensions.DoubleUnit val oneInch = 2.54.cm println(s"1インチ = $oneInch メートル") val twoFeet = 2.ft println(s"2フィート = $twoFeet メートル") |