Tana Gone
Tana Gone
1 min read

Categories

Tags

Swift5 新機能

Neverってのは何か?

これが無いとコンパイル出来ない例

func foo() {
  fatalError("fatal")
}

func bar(i: Int) -> Int {
  if i > 0 { return i }
    else { foo() }
// error: missing return in a function expected to return 'Int'
}

関数barのelse節でコンパイル・エラー発生。Intを返さないのをコンパイラーは見つけたのだ。fooの関数定義を変更するとエラー解消できる。

func foo() -> Never{
  fatalError("fatal")
}

Swiftの標準ライブラリーでは、値付き列挙子格納(付き)enumが多用

ググってみると、値付きEnumとかって出てくるけど、C言語のEnumと区別が出来ないので、上記の表現をする事にする。Success, Failure, Wrappedは型パラメーターだ。

enum Result<Success, Failure> {
  case success(Success)
  case failure(Failure)
}
Optional Value

enum Optional<Wrapped> {
  case some(Wrapped)
  case none
}

enum Never {
}

使い方は、

var a = Optional.some(1)                                                        
print(a!)
a = nil
print(a ?? "nil found")
let b = Optional<Int>.none
print(b ?? "all so nil")
a = 2
print(a!)
// rawValueキーワードで列挙子へアクセス
enum Basket: Int {
  case Melon = 1
  case Lemon
}
let raw = Basket.Melon.rawValue
let value = Basket(rawValue: 2)!
print(raw) // => 1
print(value) // => Lemon

出力は

1
nil found
all so nil
2
1
Lemon

HashableでないDictionary

let recordTimes: DictionaryLiteral = ["Florence Griffith-Joyner": 10.49,
                                      "Evelyn Ashford": 10.76,
                                      "Evelyn Ashford": 10.79,
                                      "Marlies Gohr": 10.81]
print(recordTimes.first!) // => (key: "Florence Griffith-Joyner", value: 10.49)
// Prints "("Florence Griffith-Joyner", 10.49)"
// warning: 'DictionaryLiteral' is deprecated: renamed to 'KeyValuePairs'
// note: use 'KeyValuePairs' instead
//
// (key: "Florence Griffith-Joyner", value: 10.49)

let recordTimes2: KeyValuePairs = ["Florence Griffith-Joyner": 10.49,
                                      "Evelyn Ashford": 10.76,
                                      "Evelyn Ashford": 10.79,
                                      "Marlies Gohr": 10.81]
print(recordTimes2) //                                                          
// => ["Florence Griffith-Joyner": 10.49, "Evelyn Ashford": 10.76, "Evelyn Ashfo
rd": 10.79, "Marlies Gohr": 10.81]

好きな名前のGlobal関数の生成

@dynamicCallable属性。関数ビルダーの一種。

//@dynamicCallable                                                              
struct A {
  func foo()
  { print("dynamicCallable") }
}
// => error: @dynamicCallable attribute requires 'A' to have either a valid
// 'dynamicallyCall(withArguments:)' method or
// 'dynamicallyCall(withKeywordArguments:)' method
// 関数名、ラベル、引数名、配列は変えてはイケない。
@dynamicCallable
struct B {
  func dynamicallyCall(withArguments args: [Int]) -> Void
  { print("dynamicCallable") }
}
// 使い方
let _ = B()() // => dynamicCallable

import Foundation // for pow
@dynamicCallable
struct RandomNumberGenerator {
    func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Int>) 
-> Double {
        let numberOfZeroes = Double(args.first?.value ?? 0)
        let maximum = pow(10, numberOfZeroes)
        return Double.random(in: 0...maximum)
    }
}
// 好きな名前のメソッドを作れる。randomとか、genNumとか何でも
// 名前なくてもOK
let random = RandomNumberGenerator()
let result = random(numberOfZeroes: 0)
print(result) // => 0.8926016232575397
print(RandomNumberGenerator()(numberOfZeroes: 0)) // => 0.4502460704479123

compactMapとは?

let a =                                                                         
["1", "2", "three", "4", "5"]
    .map { Int($0) }
    .filter { $0 != nil }
    .map { $0! } // [1, 2, 4, 5]

print(a)
// compactMapはnilをfilteringしてくれる。
let b =
["1", "2", "three", "4", "5"]
    .map { Int($0) }
    .compactMap { $0 } // [1, 2, 4, 5]
    
print(b)