Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Swift 3 を書くときに知っておきたい API デザインガイドライン #love_swift #akibaswift

8,894 views

Published on

Swift 3 は、ガイドラインを知っておくと変化がとっても掴みやすくなる印象。そう思って、そんな辺りについてざっくり見渡せるように資料にまとめておくことにしました。

Published in: Software
  • Be the first to comment

Swift 3 を書くときに知っておきたい API デザインガイドライン #love_swift #akibaswift

  1. 1. 話してきました
  2. 2. 
 

  3. 3. 
 
 
 

  4. 4. pointer.assignFrom(source, count: 100) pointer.assign(from: source, count: 100)
  5. 5. // album, insert photo at current page. album.insert(photo, at: currentPage) // album's photos remove all keeping capacity. album.photos.removeAll(keepingCapacity: true) // album, insert photo page current page. album.insert(photo, page: currentPage) // album's photos remove all capacity. album.photos.removeAll(capacity: true)
  6. 6. // 要素の配列 から位置 x に該当するものを消す。 associatedtype ContentView : UIView func suffix(from start: Index) -> SubSequence // 完全に役目を汲み取れなくなる例 associatedtype ViewType : UIView // 型寄りの index よりは、役割寄りの start が明瞭な例 func suffix(from index: Index) -> SubSequence
  7. 7. // 要素の配列 から、要素 x を消す。 elements.remove(x) // 要素型の x であれば“要素である”ことは自明 elements.removeElement(x) // デバイスの配列 で“element”という言葉は不適切 devices.removeElement(device) // デバイスの配列 から、デバイスを消す。 devices.remove(device)
  8. 8. // 要素の配列 から位置 x に該当するものを消す。 elements.remove(at: index) // 要素の配列 から、要素 y を消す。 elements.remove(y)
  9. 9. // 記録から、位置 x に該当する値を取得。 records.value(at: x) // 記録から、列 y 行 z に該当する値を取得。 records.valueAt(row: y, column: z) // 複数で構成時、ラベルに入れるとバランスが悪い。 records.value(atRow: y, column: z)
  10. 10. // 指定したキーに対する値を更新する。 func updateValue(_ value: Any, forKey key: String) // 名前で補足しないと、使用時に意味が汲み取れない。 updateValue(100, forKey: "A") update(100, for: "A")
  11. 11. // 主目的はメッセージの表示。第2引数以降は副次的。 func print(_ items: Any..., separator: String, terminator: String, to output: inout Target)
  12. 12. // 電子計算機の分野で、正弦関数 sin は適切な共通認識。 let answer = sin(1.5) // 言葉を適切に把握してないと、何が起こるか判らない。 rinoa.junctioned(to: Bahamut.self).megaFlare()
  13. 13. /// Inserts a new element /// into the collection at the specified index. func insert(_ newElement: _Element, at i: Index)
  14. 14. 
 
 
 

  15. 15. /// Advances to the next element and returns it, /// or `nil` if no next element mutating func next() -> Element? /// Returns a new string by concatenating the /// elements of the sequence, adding the given /// separator between each element. func joined(separator: String = default) -> String
  16. 16. /// Accesses the code unit at the given position. subscript(position: Index) -> CodeUnit { get }
  17. 17. /// Creates a view of the given string. init(_ text: String)
  18. 18. /// A raw pointer for accessing untyped data. struct UnsafeMutableRawPointer { … } /// A textual representation of the range. var description: String { get } /// Access the `Pointee` instance referenced by `self`. var pointee: Pointee { get }
  19. 19. /// Creates a new value, rounded to the closest /// possible representatation. /// /// If two representable values are equally close, /// the result is the value with more trailing /// zeros in its significand bit pattern. /// /// - Parameter value: The integer to convert /// to a floating-point value. init(_ v: Int8)
  20. 20. /// Returns the number of elements. /// /// - Complexity: O(1) if `Self` conforms /// to `RandomAccessCollection`; O(N) otherwise. var count: IndexDistance { get }
  21. 21. /// Creates a new value, rounded to the closest /// possible representatation. /// /// If two representable values are equally close, /// the result is the value with more trailing /// zeros in its significand bit pattern. /// /// - Parameter value: The integer to convert /// to a floating-point value. init(_ v: Int8)
  22. 22. let f = Double.init(_:) as (Int8) -> Double
  23. 23. // 型は名詞で名前をつける。 struct ObjectIdentifier { … } // 変数名は名詞でつける。 let identifier = ObjectIdentifier(object) // 真偽値プロパティーは主張重視。配列が空であるか。 items.isEmpty
  24. 24. // 名詞系で、自身に影響しない場合は、名詞そのまま。 let answer = value.squareRoot() // 名詞系で、自身に影響する場合は“form”接頭辞。 value.formSquareRoot() // 動詞系で、自身に影響ないなら“-ed”か“-ing”接尾辞。 let answer = value.divided(by: 3) // 動詞系で、自身に影響するなら、動詞そのまま。 value.divide(by: 3)
  25. 25. // 範囲が、ある範囲と、重なる点があるか if range1.overlaps(range2) { … } // 配列が、要素を、含んでいるか if items.contains(item) { … } // 要素を返してるのか、要素を含むか判定してるのか。 let answer = items.contained(item) { … }
  26. 26. // 内容を列挙するイテレーターを作る。 func makeIterator() -> Iterator // ボタンを作る。表題を受け取る。 func makeButton(caption: String) -> NSButton // ラベル名の英文的な流れは気にしない func makeButton(havingCaption: String) -> NSButton
  27. 27. // 同じ値を表現する場合は、素直な型変換を表現する。 let value = Int32(value64) // 再解釈を伴うなら、何が起こるかラベルで示唆する。 let value : Int32(truncatingBitPattern: value64)
  28. 28. // 列挙子の名前は小文字で始める。 enum UnicodeDecodingResult { case scalarValue(UnicodeScalar) case emptyInput case error }
  29. 29. // 具体的に“コレクション”を表現するので、名詞。 protocol Collection { … } // 比較可能性を表現するので、接尾辞“-able”な名前。 protocol Comparable { … }
  30. 30. // プロトコル名が役割と一致するなら、名称に Type を付与 associatedtype IteratorType : Iterator // ただし、標準ではプロトコル名に Protocol が主流 associatedtype Iterator : IteratorProtocol
  31. 31. // 同じ所属で、違う意味で基本名を共有している。 class Database { func index() // 索引の再構築 func index(of row: Row) -> Int // 行番号の取得 } // 所属外とは干渉しない。所属内では同じ意味。 struct Bookshelf { func index(_ i: Int, offsetBy n: Int) -> Int { … } func index(after i: Int) -> Int { … } }
  32. 32. // これらの機能は、関連している? struct String { init(_ value: Int) { … } init(_ value: Int, radix Int) { … } } // 既定値を使えば、関連性を気にする必要さえない。 struct String { init(_ value: Int, radix Int = 10) { … } }
  33. 33. // 指定したキーに対する値を更新する。 struct Variant { func value() -> Int func value() -> Double }
  34. 34. // 配列の並び替えた値、と表現できる。 struct Array<Element> { func sorted() -> Array<Element> { … } } // 所属が定まらない場合に、大域関数として扱う。 func max(_ x: Int, _ y: Int, _ z: Int) // 数値の絶対値、所属はあっても abs(x) が慣習的。 func abs(_ x: Int) -> Int
  35. 35. // もはや x, y, z は、どうでもいい。 let answer = max(x: 3, y: 5, z: 2) // 慣習的に abs(x) な書き方が自然。 let answer = abs(value: -30)
  36. 36. // Element = Any で束縛すると… struct Array<Element> { // element に [Any] が渡せる。 mutating func append(_ element: Element) { … } // elements に [Any] が渡せる。 mutating func append<S:Sequence>(_ elements: S) where S.Iterator.Element == Element { … } }
  37. 37. #if swift(>=3.0) // Swift 3.0 以上でコンパイルするコード #else // Swift 3.0 未満でコンパイルするコード #endif
  38. 38. // 新しい名前に変更する。 mutating func formUnion() { … } // 旧名称を定義、名前の変更を明記する。 @available(*, unavailable, renamed: "formUnion") mutating func unionInPlace() { /* 実装不要 */ }
  39. 39. // 新しい名前に変更する。 func advanced(by amount: Int) -> Int { … } // 旧名称を定義、名前の変更を明記する。 @available(*, unavailable, renamed: "advanced(by:)") func advancedBy(_ amount: Int) -> Never { /* 実装不要 */ }
  40. 40. // 新しい名前に変更する。 protocol Bookshelf { … } // 旧名称を型エイリアスで定義し、新しい型を設定する。 @available(*, unavailable, renamed: "Bookshelf") typealias BookshelfType = Bookshelf
  41. 41. // 列挙子を、新しい名前に変更する。 enum DecodingResult { case scalarValue(UnicodeScalar) case emptyInput case error } // 列挙子は、自動で Fix-it の対象になる。
  42. 42. // これを sorted に変えたい。 func sort() { … } // これを sort に変えたいが、旧 sort と衝突する。 mutating func sortInPlace() -> Cards { … }
  43. 43. // 旧実装はそのまま、新しい名称を指定する。 @swift3_migration(renamed="sorted()") func sort() -> Cards { … } @swift3_migration(renamed="sort()") mutating func sortInPlace() { … }
  44. 44. // 何もしなくても、マイグレーションの対象になる。 enum DecodingResult { case ScalarValue(UnicodeScalar) case EmptyInput case Error } func decode(source: String?) -> DecodingResult { … }

×