Swift 4.0の新機能

Swift 4の新機能の学習に役立つ実用的な例



Swift 4.0は、よりシンプルで安全なコードを記述できる新しい機能を備えた、多くのお気に入りのプログラミング言語の新しいバージョンです。 これは、Swift 3.0の壮大な変更ほど劇的ではなく、ほとんどの変更が既存のSwiftコードと後方互換性があることを知って喜んでいます。 もちろん、変更を加えるには時間が必要ですが、これにはそれほど時間はかかりません。



翻訳者から:
私は前もって設計と翻訳のいくつかの小さな欠陥をおaびします。 技術記事を完全に翻訳するのは私自身ではなく、他の人のためにした初めての経験です。



警告: Swift 4は、記事の執筆および翻訳の準備段階で活発に開発されており、原作者は議論のために最も興味深い有用な新機能の一部のみを選択しました。 より近いリリースでより多くの機能が利用可能になることに留意してください。



迅速なエンコードとデコード



値のタイプが大きいことはわかっていますが、 NSCodingなどのObjective-C APIとひどくやり取りすることもわかっています。何らかの種類のレイヤーを記述するか、クラスを使用する必要がありますが、どちらも不快です。 さらに悪いことに、クラスに切り替えたとしても、手作業でエンコードおよびデコードのメソッドを作成する必要があります。そのメソッドの作成は苦痛でエラーが発生しやすくなります。



Swift 4は新しいCodableプロトコルを導入します。これにより、追加のコードを記述せずに、データ型を失うことを心配せずに、独自のデータ型をシリアル化および非シリアル化できます。 さらに、データをシリアル化する方法を選択できます。クラシック形式のプロパティリストまたはJSONを使用します。



はい、すべてを正しく読みます。Swift4では、特別なコードを記述することなく、独自のデータ型をJSONでシリアル化できます。



それがどれほど美しいか見てみましょう。 まず、カスタムデータ型とそのインスタンスの一部を次に示します。



struct Language: Codable { var name: String var version: Int } let swift = Language(name: "Swift", version: 4) let php = Language(name: "PHP", version: 7) let perl = Language(name: "Perl", version: 6)
      
      





ご覧のとおり、 Codableプロトコルを言語構造に接続しました 。 このわずかな追加により、JSONに変換し、次の方法でデータとして表示できます。



 let encoder = JSONEncoder() if let encoded = try? encoder.encode(swift) { //  `encoded` - }
      
      





Swiftはデータ型内のすべてのプロパティを自動的にエンコードするため、追加のアクションを実行する必要はありません。



NSCodingを長い間使用している場合、おそらく疑問があります。これが本当に必要なものであり、どのように機能することを確認できますか? コンソールに表示できるようにDataオブジェクトを変換するためのコードを追加して、 言語構造の新しいインスタンスにデコードする必要があります。



 if let encoded = try? encoder.encode(swift) { if let json = String(data: encoded, encoding: .utf8) { print(json) } let decoder = JSONDecoder() if let decoded = try? decoder.decode(Language.self, from: encoded) { print(decoded.name) } }
      
      





JSONEncoderとPropertyListEncoderの両方には、多くのカスタマイズオプションがあります。 他のオプションの詳細については、 この新機能の開発に関する提案を参照してください。



複数行の文字列リテラル



Swiftで複数行の文字列を記述することは、行内に\ nを追加して、行の折り返しを追加することを常に意味していました。 コードでは、これはあまり良く見えませんが、少なくともユーザーに情報を正しく表示します。 幸いなことに、Swift 4は複数行の文字列リテラルの新しい構文を追加します。これにより、エスケープせずに改行を追加し、引用符を使用できますが、文字列補間などの便利な機能が利用できます。



文字列リテラルを開始するには、3つの二重引用符"" "を書いて[Enter]を押す必要があります。その後、 [Enter]を押して3つの二重引用符" 」



文字列リテラルには2つの重要なルールがあるため、改行を押すことについて明確にしたいと思います。



1) "" "を使用して行を開くと、行内容は新しい行で開始する必要があります。

2) "" "を使用して行を閉じると、この指定は新しい行の先頭にもなります。



ここに実際にあります:



 let longString = """ When you write a string that spans multiple lines make sure you start its content on a line all of its own, and end it with three quotes also on a line of their own. Multi-line strings also let you write "quote marks" freely inside your strings, which is great! """
      
      





これにより、定義内にいくつかの改行を含む新しい行が作成されます-読み取りと書き込みがはるかに簡単になります。



詳細については、 この新機能の開発に関する提案を参照してください。



KVC(キー値コーディング)のキーパスの改善



Objective-Cの最もお気に入りの機能の1つは、プロパティを直接ではなく動的に参照できることです。つまり、 「オブジェクトXがあり、ここにそのプロパティがあります」とはまったく読まずに言うことができます。 keypathと呼ばれるこれらのリンクは、プロパティへの直接アクセスとは異なります。これらのリンクは、実際に値を読み書きせず、後で使用するために単に非表示にするだけです。



以前にキーパスを使用したことがない場合は、通常のSwiftメソッドを使用してキーパスがどのように機能するかのアナロジーを示します。 StarshipおよびCrew構造を定義し、それぞれのインスタンスを1つ作成します。



 //    struct Crew { var name: String var rank: String } //  ,      struct Starship { var name: String var maxWarp: Double var captain: Crew func goToMaximumWarp() { print("\(name) is now travelling at warp \(maxWarp)") } } //     let janeway = Crew(name: "Kathryn Janeway", rank: "Captain") let voyager = Starship(name: "Voyager", maxWarp: 9.975, captain: janeway) //    `goToMaximumWarp()`  let enterWarp = voyager.goToMaximumWarp //   enterWarp()
      
      





Swiftの関数は最初のクラスの型であるため、最後の2行でgoToMaximumWarp()メソッドへの参照を作成し、後で必要に応じて呼び出すことができます。 問題は、プロパティに対して同じことができないことです。 「キャプテンの名前のプロパティへのリンクを作成することはできません。避けられない暴動が発生したときに確認できますと言うことはできません。



これはキーパスを使用して修正されます 。これらは、 enterWarp()コードのようなプロパティ参照です。 今すぐリンクを呼び出すと、現在の値が取得されますが、後でリンクを呼び出すと、最新の値が取得されます。 任意の数のプロパティを取得でき、Swiftはその出力タイプを使用して、正しいタイプを返すようにします。



Swift開発コミュニティは、他のSwiftコードと視覚的に異なるものでなければならないため、 キーパスの正しい構文について多くの時間を費やしてきました。最終的にこの構文はバックスラッシュを使用します。 .captain.name これらの値を変数に割り当てて、 スターシップ構造のインスタンスが必要なときに使用できます。 例:



 let nameKeyPath = \Starship.name let maxWarpKeyPath = \Starship.maxWarp let captainName = \Starship.captain.name let starshipName = voyager[keyPath: nameKeyPath] let starshipMaxWarp = voyager[keyPath: maxWarpKeyPath] let starshipCaptain = voyager[keyPath: captainName]
      
      





Swiftはデータ型を正しく表示できるため、これによりstarshipNameStringになり、 starshipMaxWarp - Doubleになります。 3番目の例はプロパティのプロパティを取り、Swiftもそれを正しく定義します。



詳細については、 この新機能の開発に関する提案を参照してください。



辞書機能の改善



Swift 4の最も興味深い提案の1つは、辞書に新しい機能を追加して辞書をより強力にし、特定の状況での動作を予測しやすくすることでした。



簡単な例から始めましょう。Swift3で辞書をフィルタリングしても、新しい辞書は返されません。 代わりに、フィルタリングの結果として、キーと値のラベルを持つタプルの配列( tuples )を取得します。 例:



 let cities = ["Shanghai": 24_256_800, "Karachi": 23_500_000, "Beijing": 21_516_000, "Seoul": 9_995_000]; let massiveCities = cities.filter { $0.value > 10_000_000 }
      
      





このコードの実行後、次のレコードを使用して必要なデータを取得することはできません。



 massiveCities["Shanghai"]
      
      





もはや辞書ではないからです 代わりに、次のようなコードを使用する必要があります。



 massiveCities[0].value
      
      





それはあまりクールではありません。



Swift 4以降、このコードは期待どおりに動作します-フィルタリングは新しい辞書を返します。

はい、明らかに、これは戻り値としてタプルの配列を使用する既存のコードを壊します。



同様に、辞書を使用したmap()メソッドは、多くの人が期待するほど機能しませんでした。「key-value」タイプの送信タプルを受け取りました。さらに、配列に追加された単一の値でした。 例:



 let populations = cities.map { $0.value * 2 }
      
      





これはSwift 4では現時点では変更されていませんが、新しいmapValues()メソッドが登場しました。このメソッドは、元のキーを使用して値を変換し、辞書に戻すことができるため、はるかに便利です。



たとえば、次のコードは、数値を変換し、都市の人口に関する文字列データに変換し、同じキー(上海、カラチ、ソウル)で新しい辞書に追加します。



 <let roundedCities = cities.mapValues { "\($0 / 1_000_000) million people" }
      
      





(興味がある場合、誤って重複を作成する可能性があるため、辞書キーのマッピングは安全ではありません。)



辞書への私のお気に入りの追加は、グループ化イニシャライザです。これは、シーケンスを、必要に応じてグループ化されたシーケンスの辞書に変換します。 都市の例を続けて、 cities.keysを使用して都市名の配列を返し、最初の文字でグループ化します。



 let groupedCities = Dictionary(grouping: cities.keys) { $0.characters.first! } print(groupedCities)
      
      





これにより、以下がコンソールに出力されます。



 ["B": ["Beijing"], "S": ["Shanghai", "Seoul"], "K": ["Karachi"]]
      
      





または、名前の長さに基づいて都市のグループを作成することもできます。



 let groupedCities = Dictionary(grouping: cities.keys) { $0.count } print(groupedCities)
      
      





これにより、以下がコンソールに出力されます。



 [5: ["Seoul"], 7: ["Karachi", "Beijing"], 8: ["Shanghai"]]
      
      





最後に、指定したキーが欠落している場合、辞書キーにアクセスしてデフォルト値を提供することが可能になりました。



 let person = ["name": "Taylor", "city": "Nashville"] let name = person["name", default: "Anonymous"]
      
      





さて、経験のある開発者なら誰でも、おそらく同様の結果をより簡単に達成できると主張するでしょうし、それに同意します。 Swiftの現在のバージョンでは、次のように記述できます。



 let name = person["name"] ?? "Anonymous"
      
      





ただし、辞書の値を取得するだけでなく変更する場合、これは機能しません。 このキーによるアクセスはオプションの型を返すため、辞書の値をすぐに変更することはできません-キーが存在しない可能性があります。 Swift 4のデフォルトの辞書値を使用すると、より簡潔なコードを書くことができます。例えば:



 var favoriteTVShows = ["Red Dwarf", "Blackadder", "Fawlty Towers", "Red Dwarf"] var favoriteCounts = [String: Int]() for show in favoriteTVShows { favoriteCounts[show, default: 0] += 1 }
      
      





このループは、 favoriteTVShowsの各行を反復処理し、 favouriteCounts辞書を使用して、各項目が表示される頻度を追跡します。 辞書には常に値があることがわかっているため、辞書を1行のコードに変更できます。デフォルト値として0か、以前のカウントに基づいたより大きな数値です。



詳細については、 この新機能の開発に関する提案を参照してください。



再びコレクションの列!



これは小さな変更ですが、多くの人を幸せにすることが保証されています。文字列は再びコレクションです。 これは、 それら反転し、文字を反復処理し、 map()およびflatMap()などを使用できるようになったことを意味します。 例:



 let quote = "It is a truth universally acknowledged that new Swift versions bring new features." let reversed = quote.reversed() for letter in quote { print(letter) }
      
      





この変更は、 「Line Manifesto」と呼ばれる一連の修正の一部として行われました。



一方向の範囲



最後に重要なことですが、Swift 4では、コレクションのPythonのような片側スライシングが表示され、範囲の欠落した側がコレクションの開始または終了として自動的に検出されます。 これは既存のコードへの新しいアプローチであるため、既存のコードには影響しません。したがって、コードの潜在的な故障について心配することはできません。 例:



 let characters = ["Dr Horrible", "Captain Hammer", "Penny", "Bad Horse", "Moist"] let bigParts = characters[..<3] let smallParts = characters[3...] print(bigParts) print(smallParts)
      
      





このコードは最初にこれをコンソールに出力します:



 ["Dr Horrible", "Captain Hammer", "Penny"]
      
      





そして、これ:



 ["Bad Horse", "Moist"]
      
      





詳細については、 この新機能の開発に関する提案を参照してください。



さらに来て...



記事の翻訳時点で、Xcode 9 Beta 3は、iOS 11、tvOS 11、watchOS 4、およびmacOSの新しいバージョンとともに、開発者(2017年7月7日以降)で既に利用可能です。 チームがSwift 4を可能な限り良いものにするために一生懸命働いていることは明らかであるため、すでに見たものは有望です。 これは主に、既存の機能を変更するのではなく、新しい機能を追加することに関するものです。これにより、新しい安定バージョンの言語への切り替えが容易になります。



Swiftの開発は時として混oticとすることがあるという事実にもかかわらず、Swift 4は再びAppleコミュニティのアプローチを確認しています。 いくつかの提案を追加しました。それぞれの提案は、合意に達するためにコミュニティによって広く議論されました-単にできるのは変更を強制するのはAppleエンジニアだけではなく、代わりに既にスマートでエレガントな言語を改善する合理的で思慮深いアプローチを持っているからです。



遅れている機能の1つはABI互換性です。これにより、開発者はコンパイル済みライブラリを配布できます。これは、今日のSwiftに残っている数少ない重要な機能の1つです。 Swift 5でこれに到達することを願っています...



All Articles