収穫の秋
毎年9月末の
しかしXcode 7、
そのXcode、本物ですか?
そのXcodeですが、
Apple IDさえあればβ版も無料で入手でき、
Appleもこの件に関しては、
そのXcodeが本物か否かは、spctl --assess --verbose /Applications/
を実行すればOKです。Xcodeの巨大さゆえ、
/Applications/Xcode.app: accepted source=Mac App Store
のようにacceptedを含んだ表示が出るはずです。
Apple「すべてのSwift 1.xプロジェクトを、生まれる前に消し去りたい」
それでは気を取り直して本題へ。iPhone 6sのキャッチコピーは、
前々回で私は
What's new in Swift 2
というわけで、println()
からprint()
など、
最低限文化的なenum
Swiftのenum
は、class
やstruct
と比べると微妙に使いづらいものでした。
デフォルトのdescription debugDescriptionが直感的に
たとえば、
enum Langs {
case C, Cplusplu, ObjectiveC, Swift
}
というenumがあったとして、print(Langs.
はそのままではそっけなく(Enum Value)
と表示されるだけでした。
extension Langs : Printable {
var description: String {
switch self {
case C:
return "C"
case Cplusplus:
return "C++"
case ObjectiveC:
return "Objective-C"
case Swift:
return "Swift"
}
}
}
などという具合にdescription
プロパティを定義しておく必要があったのですが、
総称型enumがまともに
Swift 1では次のコードがクラッシュしていました。
enum Either<L,R> {
case Left(L)
case Right(R)
}
総称型のEnumでは型変数が1つしか取れなかったので、
enum Optional<T> {
case None
case Some(T)
}
は定義できてもEitherのような型は作れなかったのですが、
再帰的enumが可能に
Swift 1では、
enum Cons<T> {
case Nil
case Atom(T)
case Pair(Cons, Cons)
}
enum
は値型indirect
を次のようにつけることで再帰的enumが実現可能になりました
enum Cons<T> {
case Nil
case Atom(T)
indirect case Pair(Cons, Cons)
}

もしくは、
indirect enum Cons<T> {
case Nil
case Atom(T)
case Pair(Cons, Cons)
}
ここまでそろっていたなら、
repeat { } while
Swift 1までのdo { } while
だったのですが、repeat { } while
になりました。do { }
は今後後述のdo { } catch { }
などでも用いられるようになるのと、
Option Sets
これはSwift 1.
Swift 1ではビットマップのフラグの扱いは、
let swiftGoals:Goals = .Refined ¦ .Safe ¦
.Expressive
のように、Option SetType
プロトコルに適合したstruct
を使ってより直感的にフラグを立てたり折ったりできるようになりました。
struct Goals : OptionSetType {
let rawValue : Int
static let Refined = Goals(rawValue:1)
static let Safe = Goals(rawValue:2)
static let Expressive = Goals(rawValue:4)
}
let swiftGoals:Goals = [.Refined, .Safe,
.Expressive]
if swiftGoals.contains(.Expressive){}
関数とメソッドとラベルと
Swiftでは関数もメソッドもfunc
で定義しますが……、
func f(first:String, second:Bool){ }
swtruct S {
func m(first:String, second:Bool){ }
}
Swift 1では関数は、
f("Swift", second:true)
と最初の引数のラベルが省略可能だったのに対し、
var o = S()
o.m(first:"String", second:true)
といった具合にメソッドで最初の引数のラベルは省略不能でした。Swift 2では関数の場合と同様、
使用する変数に警告
これはあくまでもXcodeの機能であってSwift2の仕様ではありませんが、var
で宣言したはずなのに一度も変更を加えていない変数は、let
で定数にするように警告するようになりました。
@testable
ユニットテストの際に1つ困るのは、public
なシンボルにしかアクセスできなかったことですが、
@testable
import MyApp
と宣言することで、
Markdown in Rich Comments
リッチコメントの中でMarkdown記法が使えるようになりました。画像すら入れられます。
guardでガード
if let
記法だと、
if let name = json["name"] {
if let year = json["year"] {
handlePerson(name, year)
} else {
handleError("year is missing")
}
} else {
handleError("name is missing")
}
たとえばPerlだったら、
my $name = $json->{name} or handlError("name is missing");
my $year = $json->{year} or handlError("year is missing");
handlePerson($name, $year);
どちらが読みやすいかは一目瞭然ですが、guard
文の導入である程度できるようになりました。
guard let name = json["name"] else {
handleError("name is missing")
}
guard let year = json["year"] else {
handleError("year is missing")
}
handlePerson(name, year)
else { }
がまだうざくはありますが、else
というのもやや違和感がありますが、
guard let something = someFunction
{ /*...*/ }
と書いてしまった場合、
guard let something = someFunction({ /*...*/ })
と解釈されてしまうおそれがあるのでこのような形になったのでしょう。
case、beyond、switch
パターンマッチは便利なものですが、switch
がうざく感じませんでしたか?
switch lang {
case .Swift(let version) where version < 2.0:
updateIt(version)
default: break
}
こういう場合に、if case
が使えるようになりました。
if case .Swift(let version) = lang where
version = < 2.0 {
upadteIt(version)
}
caseはifだけでなくforでも使えます。
for n in numbers where numbers % 2 == 0 {
handleEven(n);
}
if #available
APIバージョンによる条件コンパイルに、#available
が使えるようになりました。
override func awakeFromNib() {
if #available(OSX 10.10.3, *) {
dropButton.springLoaded = true
}
}
今までextensionをかけられたのはstruct
、enum
、class
といった実装を伴った型のみでしたが、protocol
にextension
をかけられるようになりました。
extension CollectionType {
func countIf(match: Element -> Bool) -> Int {
var count = 0
for value in self {
if match(value) { count++ }
}
return count
}
}
これは大進歩です。大進歩なので次回以降詳しく取り上げます。
Exception、ahem、error handling
おそらく巷で最も騒がれているSwift 2の新機能が、try {} catch {}
かもしれません。しかしこれはAppleが慎重にexception
という言葉を避けているように、

String is not just a sequence of characters
String自体がSequenceType
でなくなり、.characters
、.utf8
、.utf16
を必ず使うようになりました。
Swiftによる文字列の扱いもまたそのための記事を割くだけの意味があるものなので、
まとめ
そのほかにも、
- 破壊的ソートだった
sort()
がsortInPlace()
になり、非破壊的な sorted()
がsort()
になったり find()
がindexOf()
になったり.extend()
が.appendContentsOf()
になったり
などとAppleが変えたい放題変えたSwift 2ですが、
というわけで今回はSwift 2の変更点と新機能を駆け足で見てきたわけですが、
本誌最新号をチェック!
Software Design 2022年9月号
2022年8月18日発売
B5判/
定価1,342円
- 第1特集
MySQL アプリ開発者の必修5科目
不意なトラブルに困らないためのRDB基礎知識 - 第2特集
「知りたい」 「使いたい」 「発信したい」 をかなえる
OSSソースコードリーディングのススメ - 特別企画
企業のシステムを支えるOSとエコシステムの全貌
[特別企画] Red Hat Enterprise Linux 9最新ガイド - 短期連載
今さら聞けないSSH
[前編] リモートログインとコマンドの実行 - 短期連載
MySQLで学ぶ文字コード
[最終回] 文字コードのハマりどころTips集 - 短期連載
新生「Ansible」 徹底解説
[4] Playbookの実行環境 (基礎編)