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)