EZ-NET 熊⾕友宏
http://ez-net.jp/
2016.01.20
@ 集まれ Swift 好き!Swift 愛好会 #3
String Interpolation
リテラルと型の続きの話
Swift 2.1.1
謹賀新年
2016.01
本年も素敵な年になりますよう
⼼よりお祈り申し上げます
熊谷友宏
横浜 iPhone 開発者勉強会
#yidev
わいわい・ゆるく、iPhone 開発者の

みんなで楽しく過ごすのが目的の会
【 横浜・馬車道 】
カジュアル Swift 勉強会
#cswift
ゆるくみんなで Swift を語らえる場を

作りたくて始めた会
【 横浜・青葉台 】
第22回を 2016-03-05 に開催予定 第5回を 2016-02-06 に開催予定
@es_kumagai
EZ-NET http://ez-net.jp/
勉強会
熊谷友宏
Xcode 5 徹底解説 MOSA
Xcode 5 の全機能を

徹底的に解説した本
OSX/iOS 系の歴史深い

有料会員制の勉強会
紙版は絶版、電子書籍は販売中
Xcode 7 でも役立つはず 法人会員も多数
@es_kumagai
EZ-NET http://ez-net.jp/
書籍 / 登壇
熊谷友宏
@es_kumagai
EZ-NET http://ez-net.jp/
CodePiece
iOS, OS X, Apple Watch アプリ
ソースコードを Twitter と
Gist に同時投稿できる。
いつもの電卓
計算式も見える電卓アプリ。
watchOS 1 対応
音で再配達ゴッド
簡単操作で
再配達の申し込み。
EZ-NET IP Phone
iPhone でひかり電話を使う。
自宅 LAN からの利用専用
CodePiece for OS X
勉強会を楽しむアプリ
ソースコードを Twitter と Gist に同時投稿できる

勉強会で知見をみんなと共有したい時とかに便利!
できること
#__swift__
リテラルと型の
続きの話
前回のあらすじ
@ 集まれ Swift 好き!Swift 愛好会 #2
▶ コードで値を書くのに使う
▶ 具体的な内容を記述する
"Swift"
2.1
前回のあらすじ
リテラルとは
1. リテラルに型はない
2. 型がリテラルを引き受ける
前回のあらすじ
要点
リテラルに型はないQ.
リテラルはいろんな型に染まるA.
前回のあらすじ
要点 (1/2)
let value: Int = 10
let value: UInt64 = 10
let value: Double = 10
let value: NSNumber = 10
struct MyValue : IntegerLiteralConvertible {
init(integerLiteral value: Int) {
}
}
型がリテラルを引き受けるQ.
Literal Convertible プロトコルA.
前回のあらすじ
要点 (2/2)
▶ 整数リテラル
▶ 小数点数リテラル
▶ 真偽値リテラル
▶ 文字列リテラル
▶ nil リテラル
▶ 配列リテラル
▶ 辞書リテラル
… 3
… 3.1
… true, false
… "STRING"
… nil
… [ value, ... ]
… [ key : value, ... ]
リテラルの種類
前回のあらすじ
リテラルと型の関係性
前回のあらすじ
true は Bool型?Q.
Bool型が true を真として扱うA.
NSNumber 型も真として扱うA.
let value: Bool = true
let value: NSNumber = true
着目したいところ
文字列リテラル
"Swift"
▶ 引用符で括って文字列を表現
▶ 特別な文字も挿入可能
"Swift" // Swift
""Swift"" // "Swift"
"Header:tText" // Header: Text
"!u{20DD}" // ! ⃝
概要
文字列リテラル
こんな書き方もできる
"Swift (version)"
let version = 2.1
let text = "Swift (version)"
print(text)
"Swift (version)" と書くと?Q.
変数が実際の値に差し替えられるA.
文字列リテラル
値を挿入できる文字列表現
Swift 2.1
違和感
1. リテラルに型はない…?
2. 型がリテラルを引き受ける…?
文字列リテラル
リテラルに値を挿入できる?
let text: String = "Swift (version)"
リテラルに
型が混ざる?
具体的な
値じゃない…
結果を返す
関数みたい…
埋め込みなんて
想定してた…?
本当に型が

受け入れてる?
リテラル自身が
埋め込むの?
リテラル自身が
振る舞えるの?
能動的に動けすぎ…?
本当にリテラルなのか?Q.
試してみるしかないでしょう!A.
文字列リテラル
値を挿入できる文字列表現
1. リテラルを受け入れる型を作って、
2. 代入する。
値を挿入した文字列
リテラルなのか確かめてみる
struct MyValue:StringLiteralConvertible {
}
let version = 2.1
let value: MyValue = "Swift (version)"
Cannot convert value of type 'String' to specified type 'MyValue'
( ̄▽ ̄)
String Interpolation
文字列補間構文
Swift uses string interpolation to include the name of a
constant or variable as a placeholder in a longer string, and
to prompt Swift to replace it with the current value of that
constant or variable. Wrap the name in parentheses and
escape it with a backslash before the opening parenthesis:
The Swift Programming Language
println("The current value of
friendlyWelcome is (friendlyWelcome)")
▶ 文字列の中に値を埋め込む仕組み
▶ (value) という書式で埋め込む
// value の値は "Swift 2.1" になる
let version = 2.1
let value = "Swift (version)"
要点
String Interpolation
▶ 計算式も埋め込み可能
▶ メソッド実行や末尾クロージャー使用も可能
"(values)"
"(values.count)"
"(values.contains("2"))"
"(values.map { $0 * 2 } .reduce(0, combine: +))"
自由度の高い書式
String Interpolation
プロトコルも存在
String Interpolation を想定した
▶ 型が String Interpolationを

受け入れることを表明するプロトコル
▶ 複雑な書式をパーツ毎に分解して変換する
protocol StringInterpolationConvertible {
init(stringInterpolation strings: Self...)
init<T>(stringInterpolationSegment expr: T)
}
StringInterpolationConvertible
プロトコル
1. init<T>(stringInterpolationSegment: T)
2. init(stringInterpolation: Self...)
StringInterpolationConvertible
必須の実装
String Interpolation の各パーツを

順に受け取って自身の型に変換する
各パーツを変換した値の配列から

最終的な値を組み立てる
変換の流れ
StringInterpolationConvertible
"Language_(lang)_Version_(ver)"
型
"Language_" """_Version_" verlang
値 値 値 値 値
Array<型>
値
init(stringInterpolation:)
init<T>(stringInterpolationSegment:)
変換処理はオーバーロード可能
StringInterpolationConvertible
値 値 値 値 値
Array<型>
init(stringInterpolationSegment:String)
init<T:LanguageType>(stringInterpolationSegment:T)
init<T:Any>(stringInterpolationSegment:T)
"Language_" """_Version_" verlang
String Interpolation 対応
自作の型を対応させる
目標
1. 型をString Interpolationに対応
2. 整数値は3桁区切りの文字列で表現
3. 整数値以外は文字列で表現
4. 各パーツをまとめて完成
String Interpolation 対応
▶ 型でString Interpolationの受け入れを表明
▶ StringInterpolationConvertibleを適用
struct FormattedString : StringInterpolationConvertible {
// このプロパティで文字列を表現
var value: String
型をString Interpolationに対応
String Interpolation 対応 (1/4)
▶ 整数型の値を変換する処理
▶ 自身の型で3桁区切りの文字列を表現
struct FormattedString : StringInterpolationConvertible {
// 整数型を受け取った場合は、3桁区切りの文字列にする
init<T:IntegerType>(stringInterpolationSegment expr:T) {
let value = NSNumber(longLong: expr.toIntMax())!
let formatter = NSNumberFormatter()
formatter.numberStyle = .DecimalStyle
self.value = formatter.stringFromNumber(value)
整数値は3桁区切りの文字列で表現
String Interpolation 対応 (2/4)
▶ 整数型以外の値を変換する処理
▶ 自身の型に そのまま文字列で表現
struct FormattedString : StringInterpolationConvertible {
// 整数型以外を受け取った場合は、そのまま文字列にする
init<T>(stringInterpolationSegment expr: T) {
self.value = String(expr)
}
整数値以外は文字列で表現
String Interpolation 対応 (3/4)
▶ 最後に変換済みの全パーツを取得
▶ それらを使って自身の型を再構築
struct FormattedString : StringInterpolationConvertible {
// 変換済みの全てのパーツを文字列として連結して、完成
init(stringInterpolation strings: FormattedString...) {
self.value = strings.reduce("") { $0 + $1.value }
}
各パーツをまとめて完成
String Interpolation 対応 (4/4)
完成
▶ String Interpolationを記載
▶ それが自作型であることを明記
let version = 2000
let string: FormattedString = "Windows (version)"
完成した型を使う
String Interpolation 対応
// 実行結果
Windows 2,000
print(string.value)
おしまい
リテラルと型の続きの話
まとめ
リテラルと型の続きの話
1. 前回のあらすじ
リテラルとは
リテラルに型はない
型がリテラルを引き受ける
2. 着目したいところ
文字列に値を挿入できる
これって本当にリテラル?
3. String Interpolation(文字列補間構文)
文字列に値を挿入できる表現
自作の型を 文字列補間構文 に対応させる

リテラルと型の続きの話 #__swift__