swift 3 で新しくなったところ - 表面から見えにくいところを中心に紹介...
TRANSCRIPT
// 型は名詞で名前をつける。 struct Queue { … }
// 変数名は名詞でつける。 let queue = Queue()
// 真偽値プロパティーは主張重視。配列が空であるか。 items.isEmpty
// item は items が扱う主体 items.add(item)
// index は items が扱う主体ではない items.remove(at: index)
// 複数で位置を示すときは前置詞を名前に含めることも items.moveTo(x: 3, y: 5)
// 名詞系で、自身に影響しない場合は、名詞そのまま。 let answer = value.squareRoot()
// 名詞系で、自身に影響する場合は“form”接頭辞。 value.formSquareRoot()
// 動詞系で、自身に影響ないなら“-ed”か“-ing”接尾辞。 let answer = value.divided(by: 3)
// 動詞系で、自身に影響するなら、動詞そのまま。 value.divide(by: 3)
// 範囲が、ある範囲と、重なる点があるか if range1.overlaps(range2) { … }
// 配列が、要素を、含んでいるか if items.contains(item) { … }
// 要素を返してるのか、要素を含むか判定してるのか。 let answer = items.contained(item) { … }
// 列挙子の名前は小文字で始める。 enum Drink { case coffee case tea case water }
// キューの最初、と表現できる。 extension Queue { func first -> Element? { … } }
// 所属が定まらない場合に、大域関数として扱う。 func max(_ x: Int, _ y: Int, _ z: Int)
// 数値の絶対値、所属はあっても abs(x) が慣習的。 func abs(_ x: Int) -> Int
class Controller : UIViewController {
@IBOutlet var titleLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
titleLabel.text = "ISAO meetup" }
}! や ? で中身を取り出す操作をしなくても自動で取り出される
Type!
Type?
let value: Type!
// 型に ! を添えて定義する(従前どおり) let implicitly: Int! = 100
// 型明記せずに受けると、その変数は普通の Optional 型 let optional = implicitly
Int?
// Int! を返す関数があったとき … func something() -> Int! {…}
// 暗黙アンラップとして即使用する方法(受け手は戻り値の型) let result = something().advanced(by: 1)
// 速やかに解消する方法(受け手は Int 型) let result = something()!
// nil の可能性を残して先へ(受け手は Int? 型) let result = something()
let values = Array<Int!>
// Int! 型のまま持ち歩くのを防ぐことで、 // 取り出した時に初めて nil だったことに気づくのを予防
for value in 0 ..< 100 {
} CountableRange<Int> : Sequence
1
1
2
3
5
1
1
1
1
2
3
1
1
1
struct Fibonacci : Sequence { struct Iterator : IteratorProtocol { fileprivate var data = (0, 1) mutating func next() -> Int? { defer { data = (data.1, data.0 + data.1) } return data.1 } } func makeIterator() -> Iterator { return Iterator() } }
let fibonacci = AnySequence { () -> AnyIterator<Int> in
var data = (0, 1)
return AnyIterator {
defer {
data = (data.1, data.0 + data.1) }
return data.1 } }
var previous2 = 0 let fibonacci = sequence(first: 1) { previous1 in
defer { previous2 = previous1 }
return previous1 + previous2 }
let fibonacci = sequence(state: (0, 1)) { (state: inout (Int, Int)) -> Int? in
defer { state = (state.1, state.0 + state.1) }
return state.1 }
// Swift 3 での探し方 let value: Int? = fibonacci.first { $0 > 100 }
// Swift 2 での探し方 var value: Int? { for v in fibonacci where v > 100 { return v } return nil }
// 次のインデックスを取得 let next = index.successor()
// 前のインデックスを取得 let previous = index.predeessor()
// 扱うインデックスの範囲 let indices = items.indices
// あるインデックスの次を取得 let next = items.index(after: index)
// あるインデックスの前を取得 let previous = items.index(before: index)
Kumagai Sato TanakaKudo
successor successorpredecessor
Kumagai
Kudo
Sato
Tanaka
開始インデックス
終端インデックス
index(before: "Kumagai")
index(after: "Kumagai")
index(after: "Sato")
// 指定した距離だけ先のインデックスを取得
items.startIndex.advancedBy(5) items.index(items.startIndex, offsetBy: 5)
// インデックス間の距離を取得
items.startIndex.distanceTo(items.endIndex) items.distance(from: items.startIndex, to: items.endIndex)
var currentValue = 0
let closure = { () -> Int in
currentValue += 1
return currentValue }
内側で、外の変数をそのまま使える
// 明記がないものは、非エスケープなクロージャー func doSomething(predicate: () -> Int) { }
// エスケープ可能にしたい場合は、明記が必要に func doSomething(predicate: @escaping () -> Int) { }
func transfer(content: Data, completionHandler: @escaping () -> Void) {
// 非同期処理など、別のスコープへ渡せる DispatchQueue.main.async {
completionHandler() } }
func transfer(content: Data, completionHandler: () -> Void) {
// 非同期処理など、別のスコープへ持ち出せない DispatchQueue.main.async {
completionHandler() } }
// たとえ、素性の知れない関数であっても … func callBlackBox(predicate: () -> Int)
// @noescape なら循環参照の心配はない callBlackBox { return self.items.count }
クロージャー
変数
変数 Non-Escapeクロージャー
変数
クロージャー
変数
変数
変数
Escapingクロージャー
クロージャー obj Escapingクロージャー
プロパティー
obj: Object
class Object {
var completion: (() -> Void)?
func request(completion f: @escaping ()->Void) {
…; completion = f } }
let obj = Object()
// 循環参照を起こすか、外からはわかりづらい obj.request { print(obj) }