iOS11と一緒に、Swift4も出されました。Swift3と比べて何が違うのか、みてみましょう。

1. String

1.1 Multi-line string宣言

Swift4ではpythonのように複数ラインの文字列宣言ことができるようになります。

1.2 Stringの扱い

Stringがcollectionのように扱われています。

let message = "Message!"
message.count // Swift 3 以前:message.characters.count
for character in message {  // Swift 3 以前:message.characters
    print(character)
}

結果:

M
e
s
s
a
g
e
!

 

1.3 Unicode 9をサポート

以下の全ての文字数が1になります。

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

 

2. Collection

2.1 新しいSwap関数

要素のインデックスで指定して交換することができます。

var names = [“Vipul”,”Vinay”,”Vishal”,”Akshay”]
names.swapAt(2,3)

結果:

[“Vipul”, “Vinay”, “Akshay”, “Vishal”]

 

2.2 One-sided Ranges

let names = [“Vipul”, “Vishal”, “Vinay”, “Vikas”, “Vineet”]
let firstTwoString = names[..<2]
let lastThreeString = names[2…]
print(firstTwoString)
print(lastThreeString)

結果:

["Vipul", "Vishal"] // [..<2] => [0,1]
["Vinay", "Vikas", "Vineet"] // [2…] => [2,3,4]

 

3. Dictionary

3.1宣言

配列からDictionary宣言ができるようになります。

let friends = [“Vipul”, “Vinay”, “Vishal”]
let friendsDictionary = Dictionary(uniqueKeysWithValues: zip(1…, friends))
print(friendsDictionary)

結果:

[1: “Vipul”, 2: “Vinay”, 3: “Vishal”]

 

3.2 キーが存在してない時のデフォルト値

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

Swift3は nil coalescingを使って同じこと実装できますが、

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

Swift4の書き方ではコードがより簡潔になります。

var favoriteTVShows = ["Red Dwarf", "Blackadder", "Fawlty Towers", "Red Dwarf"]
var favoriteCounts = [String: Int]()

for show in favoriteTVShows {
    favoriteCounts[show, default: 0] += 1
}

 

3.3 Mapping value

Dictionaryをフィルタリングした後、戻り値がDictionaryではなく、実際は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がもうDictionaryではないため、massiveCities[“Shanghai”]値がよめなくなります。

かわりに、massiveCities[0].valueで値をとるしかないです。それはあまりかっこよくないね。

同じようにmap()もTuplesの配列が戻されます。

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

それらの関数はSwift4でもかわらないですが、mapValues()という新しい関数が追加されました。

mapValues()で実行した後の戻り値がDictionary型で、直接キーで値をとることが可能になりました。

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

 

3.4 Grouping

町の最初の文字によるグルーピング:

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"]]

 

4. Encode & Decode

Swift4でJSONエンコーダー&デコーダーがbuilt-inされたため、外部のライブラリなどが不要になります。

モデル宣言:

struct Address:Codable {
  var street:String
  var zip:String
  var city:String
  var state:String
}

struct Person: Codable {
  var name: String
  var address: Address
}

内容をいれてみると

let address = Address(street: “Apple Bay Street”, zip: “94608”, city: “Emeryville”, state: “California”)
let person = Person(name: “Steve Jobs”, address: address)

Encoding ( Model -> JSON )

let encoder = JSONEncoder() // Define JSONEncoder
if let encoded = try? encoder.encode(person) {
  if let json = String(data: encoded, encoding: .utf8) {
    print(json)
  }
}

結果はこのようになります:

{“name”:”Steve Jobs”,”address”:{“state”:”California”,”street”:”Apple Bay Street”,”zip”:”94608",”city”:”Emeryville”}}

Decoding ( JSON -> Model )

let decoder = JSONDecoder()
if let decoded = try? decoder.decode(Person.self, from: encoded) {
  print(decoded.name)
  print(decoded.address)
}

結果:

Steve Jobs
Address(street: “Apple Bay Street”, zip: “94608”, city: “Emeryville”, state: “California”)

 

5. Keypaths

オブジェクトから自分のすべてのプロパティをアクセスする方法です。

keyPathが \ の演算子からはじまります。

モデル宣言:

struct Address {
  var street:String
  var zip:String
  var city:String
  var state:String
}

struct Friend {
  var name: String
  var addresses: [Address]

  var primaryAddress: Address {
      return addresses.first!
  }
}

内容をいれてみると

let address1 = Address(street: “Apple Bay Street”, zip: “94608”, city: “Emeryville”, state: “California”)
let address2 = Address(street: “27th Way”, zip: “85042”, city: “Phoenix”, state: “Arizona”)
let friend = Friend(name: “Steve Jobs”, addresses: [address1,address2])

たとえば、Californiaの値をとりたい時、keyPathでとることができます:

print(friend[keyPath:\Friend.primaryAddress.state])

結果:

California

投稿者プロフィール

L. Kai
L. Kai