Swift 4で私たちを待っているのは何ですか?

目次


  1. 一方向の範囲
  2. 行
  3. プライベート広告は、同じファイルの拡張子に表示されます。
  4. スマートウェイキー
  5. アーカイブとシリアル化
  6. 辞書とセットの改善
  7. MutableCollection.swapAtメソッド
  8. inoutサポートで削減
  9. 下付き文字のジェネリック
  10. NSNumberのブリッジ
  11. クラスとサブタイプのインスタンス

すべてを自宅で開始する方法は?


  1. サイトから最新のSwift 4スナップショットをダウンロードします
  2. インストーラーを実行する
  3. Xcode> Toolchains> Manage Toolchainsに移動し、スナップショットを選択します


一方向の範囲


SE-0172は、新しいRangeExpressionプロトコルと、下限または上限が定義されていない一方向範囲を定義するためのプレフィックス/ポストフィックス演算子のセットを追加します。


無限のシーケンス


一方向シーケンスを使用して、無限シーケンスを作成できます。 番号付けをゼロから開始したくない場合、これはenumerated()より柔軟な代替です。


 let letters = ["a","b","c","d"] let numberedLetters = zip(1..., letters) Array(numberedLetters) 

コレクションの添字


コレクションの添字で一方向のシーケンスが使用される場合、 startIndexまたはendIndexは、それぞれコレクション内の欠落している上部または下部の境界を個別に「埋める」。


 let numbers = [1,2,3,4,5,6,7,8,9,10] numbers[5...] //  numbers[5..<numbers.endIndex] 

パターン比較


パターン比較とは、一方向シーケンスがパターン比較構造で使用されるcaseです。たとえば、 caseやswitchです。 ここでは、コンパイラがswitchが冗長であることをまだ判断できないことに注意してください 。


 let value = 5 switch value { case 1...: print("greater than zero") case 0: print("zero") case ..<0: print("less than zero") default: fatalError("unreachable") } 

行


複数行の文字列リテラル


SE-0168は、複数行の文字列リテラル( """ )の簡単な構文を導入します。複数行のリテラルでは、単一引用符をエスケープする必要がないため、JSONやHTMLなどの形式をエスケープせずに挿入できます。各行の先頭から削除されるスペースの数。


 let multilineString = """ This is a multi-line string. You don't have to escape "quotes" in here. The position of the closing delimiter controls whitespace stripping. """ print(multilineString) 

printの結果を確認するには、( 表示>デバッグ領域>コンソールのアクティブ化 )をクリックしてコンソールを表示できます。


行今コレクション


SE-0163は、Swift 4の改訂された文字列モデルの最初の部分です。最大の変更点は、文字列が(Swift 1.xで使用されていたように)コレクションであるということです。 (他のビュー、 UnicodeScalarView 、 UTF8View 、およびUTF16Viewがまだ存在しています。)


SE-0163はまだ完全には実装されていないことに注意してください。今後さらに厳しい変更が加えられる予定です。


 let greeting = "Hello, !" //      .characters greeting.count for char in greeting { print(char) } 

部分文字列-ラインスライスの新しいタイプ


行スライスインスタンスは、 Substringタイプになりました。 StringとStringProtocol両方がStringProtocolプロトコルを実装します。 ほとんどすべての文字列APIはStringProtocolに存在するため、 StringとStringProtocol基本的に同じように動作します。


 let comma = greeting.index(of: ",")! let substring = greeting[..<comma] type(of: substring) // API  String    Substring print(substring.uppercased()) 

Unicode 9


Swift 4はUnicode 9をサポートし、現代の絵文字の適切な書記素クラスタリングの問題を修正します。 以下はすべて単一の文字になりました。


 "".count // person + skin tone "‍‍‍".count // family with four members "\u{200D}\u{200D}\u{200D}".count // family + skin tones "‍".count // person + skin tone + profession 

Habraparserはすべての絵文字を飲み込んだので 、 こちらで見てください


Character.unicodeScalarsプロパティ


これで、 Characterポイントを文字列に変換せずに、文字ポイントに直接アクセスできます( SE-0178 )。


 let c: Character = "" Array(c.unicodeScalars) 

プライベート広告は、同じファイルの拡張子に表示されます。


SE-0169はアクセス制御ルールを変更して、同じファイル内の親タイプの拡張子でプライベートアナウンスが表示されるようにしました。 これにより、タイプ定義をいくつかの拡張子に分割し、ほとんどの「プライベート」なものにプライベートアクセスを使用して、 fileprivateアクセスfileprivate必要性を減らすことができfileprivate 。


 struct SortedArray<Element: Comparable> { private var storage: [Element] = [] init(unsorted: [Element]) { storage = unsorted.sorted() } } extension SortedArray { mutating func insert(_ element: Element) { // storage   storage.append(element) storage.sort() } } let array = SortedArray(unsorted: [3,1,2]) // storage __   (   fileprivate) //array.storage // error: 'storage' is inaccessible due to 'private' protection level 

スマートウェイキー


おそらくSwift 4の主な機能の1つは、 SE-0161で説明されている新しいキーパスモデルです。 Cocoa文字列パスキーとは異なり、Swiftパスキーは厳密に入力されます。


 struct Person { var name: String } struct Book { var title: String var authors: [Person] var primaryAuthor: Person { return authors.first! } } let abelson = Person(name: "Harold Abelson") let sussman = Person(name: "Gerald Jay Sussman") let sicp = Book(title: "Structure and Interpretation of Computer Programs", authors: [abelson, sussman]) 

パスキーは、ルートタイプから指定して、プロパティと名前の任意の組み合わせにドロップできます。


\Book.titleは、バックスラッシュで始まります: \Book.title 。 Swiftのすべての型は、 [keyPath: …] - [keyPath: …]の値を取得または設定するための添え字を受け入れます。


 sicp[keyPath: \Book.title] //        sicp[keyPath: \Book.primaryAuthor.name] 

KeyPathは、格納および操作できるKeyPathオブジェクトです。 たとえば、パスキーにセグメントを追加して、さらに深くすることができます。


 let authorKeyPath = \Book.primaryAuthor type(of: authorKeyPath) let nameKeyPath = authorKeyPath.appending(path: \.name) //          sicp[keyPath: nameKeyPath] 

パスキーの添え字


パスキーで添え字表記を使用することもできます。 コレクション、配列、または辞書を操作する非常に便利な方法。 この機能は、現在のスナップショットにはまだ実装されていません。


 //sicp[keyPath: \Book.authors[0].name] // INTERNAL ERROR: feature not implemented: non-property key path component 

アーカイブとシリアル化


SE-0166:Swift Archival&Serializationは、Swiftの型(クラス、構造体、および列挙)がシリアル化およびアーカイブする方法を定義します。 Codableプロトコルを実装することにより、型は(一度)アーカイブされるようにCodableます。


ほとんどの場合、必要なのはCodableプロトコルの実装だけです。 コンパイラは、型のすべてのメンバーがCodable実装する場合にのみ、実装自体の残りを生成できます。 型のシリアル化方法を変更する必要がある場合は、標準の動作をオーバーライドすることもできます。 このトピックには多くのニュアンスがあります-詳細については、オファーを確認してください。


 //     (   )   Codable struct Card: Codable { enum Suit: String, Codable { case clubs, spades, hearts, diamonds } enum Rank: Int, Codable { case ace = 1, two, three, four, five, six, seven, eight, nine, ten, jack, queen, king } var suit: Suit var rank: Rank } let hand = [Card(suit: .clubs, rank: .ace), Card(suit: .hearts, rank: .queen)] 

コーディング


Codableを実装する値がある場合、アーカイブするためにエンコーダーに渡す必要があります。


Codableのインフラストラクチャを使用する独自のエンコーダーおよびデコーダーを作成できますが、SwiftはJSON( JSONEncoderおよびJSONDecoder )およびプロパティのリスト( PropertyListEncoderおよびPropertyListDecoder )の組み込みを提供します。 それらはSE-0167で定義されています。 NSKeyedArchiverは、すべてのCodableタイプもサポートします。


 import Foundation var encoder = JSONEncoder() //   JSONEncoder    encoder.dataEncodingStrategy encoder.dateEncodingStrategy encoder.nonConformingFloatEncodingStrategy encoder.outputFormatting encoder.userInfo let jsonData = try encoder.encode(hand) String(data: jsonData, encoding: .utf8) 

デコード


 let decoder = JSONDecoder() let decoded = try decoder.decode([Card].self, from: jsonData) 

DictionaryとSet改善


SE-0165は、 DictionaryおよびSetいくつかの機能強化を追加します。


シーケンス初期化子


キーと値のペアのシーケンスから辞書を作成します。


 let names = ["Cagney", "Lacey", "Bensen"] let dict = Dictionary(uniqueKeysWithValues: zip(1..., names)) dict[2] 

Merge InitializerとMergeメソッド


これで、シーケンスからディクショナリが作成されるとき、またはシーケンスが現在のディクショナリにマージされるときに、重複キーがどのように処理されるかを決定できます。


 let duplicates = [("a", 1), ("b", 2), ("a", 3), ("b", 4)] let letters = Dictionary(duplicates, uniquingKeysWith: { (first, _) in first }) letters let defaults = ["foo": false, "bar": false, "baz": false] var options = ["foo": true, "bar": false] //      : error: generic parameter 'S' could not be inferred //       https://bugs.swift.org/browse/SR-922 //options.merge(defaults) { (old, _) in old } 

デフォルト値の添え字


存在しないキーのデフォルト値を添え字の引数として定義して、戻り値のタイプをオプションにできません。


 dict[4, default: "(unknown)"] //       

これは、添え字を使用して値を変更する必要がある場合に特に重要です。


 let source = "how now brown cow" var frequencies: [Character: Int] = [:] for c in source { frequencies[c, default: 0] += 1 } frequencies 

辞書固有のmapとfilter


filterはArrayではなくDictionaryを返します。 同様に、新しいmapValuesメソッドは、構造mapValues維持しmapValues値mapValues変換します


 let filtered = dict.filter { $0.key % 2 == 0 } type(of: filtered) let mapped = dict.mapValues { value in value.uppercased() } mapped 

Set.filterは、 ArrayではなくSetも返します。


 let set: Set = [1,2,3,4,5] let filteredSet = set.filter { $0 % 2 == 0 } type(of: filteredSet) 

シーケンスのグループ化


値のシーケンスを花束にグループ化します。 リスト内の単語を最初の文字で区切ります。


 let contacts = ["Julia", "Susan", "John", "Alice", "Alex"] let grouped = Dictionary(grouping: contacts, by: { $0.first! }) grouped 

MutableCollection.swapAtメソッド


SE-0173は、コレクション内の2つのアイテムを交換する新しい方法を導入しています。 既存のswap(_:_:)とは異なり、 swapAt(_:_:)メソッドは、( inout引数を介して)要素自体ではなく、交換される要素のインデックスを受け入れます。


このメソッドを追加する理由は、2つのinout引数との共有には互換性がないためです。
新しいSE-0176メモリアクセスルール。 既存のswap(_:_:)関数swap(_:_:)は、同じコレクションの2つの要素を交換するために機能しなくなります。


 var numbers = [1,2,3,4,5] numbers.swapAt(0,1) // Will be illegal in Swift 4 (not implemented yet) swap(&numbers[3], &numbers[4]) numbers 

inoutサポートでreduce


SE-0171は、結果が入力関数としてcombine関数に渡されるreduceメソッドオプションを追加します。 これは、 reduceと中間結果を排除することで、 reduceを使用してシーケンスをインクリメンタルに構築reduceアルゴリズムの大幅な加速になります。


SE-0171はまだ実装されていません


 //     extension Sequence where Iterator.Element: Equatable { func uniq() -> [Iterator.Element] { return reduce(into: []) { (result: inout [Iterator.Element], element) in if result.last != element { result.append(element) } } } } [1,1,1,2,3,3,4].uniq() 

下付き文字のジェネリック


SE-0148に示されているように、添え字はジェネリックの形式で引数を受け入れて返すことができるようになりました。


正規の例は、 JSONデータを表す型です。一般的な添え字を定義して、呼び出し元のコードのコンテキストが期待される戻り値の型を決定できるようにすることができます。


 struct JSON { fileprivate var storage: [String:Any] init(dictionary: [String:Any]) { self.storage = dictionary } subscript<T>(key: String) -> T? { return storage[key] as? T } } let json = JSON(dictionary: [ "name": "Berlin", "country": "de", "population": 3_500_500 ]) //     as? Int let population: Int? = json["population"] 

別の例: Collection添字。一連のインデックスを受け取り、これらのインデックスの値の配列を返します。


 extension Collection { subscript<Indices: Sequence>(indices indices: Indices) -> [Iterator.Element] where Indices.Iterator.Element == Index { var result: [Element] = [] for index in indices { result.append(self[index]) } return result } } let words = "Lorem ipsum dolor sit amet".split(separator: " ") words[indices: [1,2]] 

NSNumberブリッジ


SE-0170は、Swiftの数値型とNSNumber間のブリッジに関するいくつかの危険な動作を修正します。


 import Foundation let n = NSNumber(value: UInt32(543)) let v = n as? Int8 // nil in Swift 4. This would be 31 in Swift 3 (try it!). 

クラスとサブタイプのインスタンス


これで、SwiftのObjective-C UIViewController <SomeProtocol> *に同等のコードを記述できます。
たとえば、特定のタイプの変数を宣言し、1つ以上のプロトコルに同時にバインドします( SE-0156 )。 構文let variable: SomeClass & SomeProtocol1 & SomeProtocol2


 import Cocoa protocol HeaderView {} class ViewController: NSViewController { let header: NSView & HeaderView init(header: NSView & HeaderView) { self.header = header super.init(nibName: nil, bundle: nil)! } required init(coder decoder: NSCoder) { fatalError("not implemented") } } //    NSView     // ViewController(header: NSView()) // error: argument type 'NSView' does not conform to expected type 'NSView & HeaderView' //    NSView ()      extension NSImageView: HeaderView {} ViewController(header: NSImageView()) //  


Source: https://habr.com/ru/post/J329580/


All Articles