読者です 読者をやめる 読者になる 読者になる

謎言語使いの徒然

適当に気になった技術や言語を流すブログ。

Swift 言語のホワイトペーパー眺めてみた

Swift 日記 勉強

言語仕様が scala じみてると言われるが、個人的にシンタックスCoffeeScript に近い気がする。 let とか var の書き方は F# に近い印象? if, for が statement (句)って言ってるのが残念。function で居て欲しかった。 型宣言は Scala か、デフォルトで null 禁止はいいね。nullable にする場合 ? 修飾って C#?

var optionalName: String? = "John Appleseed”
var greeting = "Hello!"

if let name = optionalName {
    greeting = "Hello, \(name)"
}

if let は optionalName を評価して値が入ってれば {} の結果を name に設定する。 nil だとコードブロックは無視されて name に nil が入るのか。 短い構文発見

var optionalName: String? = "John Appleseed”

let nameLength = optionalName?.length()

基本的に nil は false として条件判定出来るらしい。 ってかこれ scala だとこうなる。

val optionalName = Some("John Appleseed")
val greeting = "Hello"
val name = optionalName.map(s => s"Hello, $s")

正直、filter, foreach とか欲しかった。 isDefined 要らずは良いけどね。 switch - case 文は Scala の match - case 式に近い印象。 ガード条件で処理が書けるのは正直ありがたい。 foreach の記述が

let hash = [
  "azalea":[2,4,8,16],
  "armeria":[1,3,5,7]
]
for (name, value) in hash {
  for num in value {
    println("Name \(num) comtains \(num)")
  }
}

でイテレート可能か。 for-in 句だと Coffee の方が近いか。 while, do-while 句もあるのか。 ただしこの扱いはやはり構文(statement)なので、return してこない。マジ残念。

関数型として高階関数が仕えるのはいい。 function の定義式が下記。

func functionName(arg: ArgType) -> ReturnType {
  return ...
}

関数もネストすれば高階にできる。 ってーかカリー化マダー?

一応関数型だけあって、イテレート可能型に map 関数が存在するのはいい感じだ。

let nums = [1,2,4,8,16]
nums.map({ (num: Int) -> Int in
  return num * 2
})

1行省略

let nums = [1,2,4,8,16]
nums.map({ num in num * 2 })

引数参照を使えば引数名を省略できる

let nums = [1,2,4,8,16]
nums.map({ $0 * 2 })

個人的に関数と定数・変数の型宣言に一貫性が無いのは気になった。

let name: String = "HAHAHA"
func getName() -> String { return name }

比較対象:scala

val name: String = "HAHAHA"
def getName(): String = name

object 指向もなかなかいい感じ。

class Name {
  var name: String
  init(name: String) {
    self.name = name
  }
  func getName() -> String { return self.name }
}

ただし、コンストラクタがこの形状だと、クラス内に定数を置くのがやや面倒か。

class Name {
  let name: String // これは初期化できない
  init(name: String) {
    self.name = name
  }
  func getName() -> String { return self.name }
}

親クラス参照は super で、親コンストラクタsuper.init() でアクセス出来る。 どうも「親コンストラクタコンストラクタの第一行でしか呼べない」という様な仕様はないらしい。

継承自体も結構シンプル

class Base {
  var n: String
  init(n: String) { self.n = n }
  var prop: String {
    get { return self.n }
    set { self.n = "Set: \(newValue)" }
  }
  func hello() -> String {
    return "Hello, \(self.n)"
  }
}

class Child: Base {
  init() {
    super.init("HAHAHA")
  }
  override func hello() -> String {
    return "Child : \(self.n)"
  }
}

フィールドのアクセス権限はデフォルトで public らしい。 willSet, didSet は objective-c のKVOに相当するのか? それぞれ値を設定される直前、直後に実行されるコールバック

class User {
  var name: String {
    willSet { nameLength = newVakue.length() }
  }
  
  var nameLength: Int
}

いや、この言語の String に length メソッドあるか知らないけどさ…

enumscala よりいい感じ(つーか scala のアレが悪名高杉w)

enum Employee: Int {
  case CEO = 1
  case CTO, Sales, Developper
  
  func desc() -> String {
    case .CEO:
      return "社長"
    case .CTO:
      return "最高技術責任者"
    case .Sales:
      return "営業"
    case .Developper:
      return "開発"
  }
}

let hira = Employee.Deevelopper
println(hira.desc())

今日はここまで。