SwiftでInt?をCGFloat?にしたい
Swiftの関数でオプショナル型の整数をもらって、それがnilならnilで、値があるならCGFloatに(つまりCGFloat?に)したい。
//(1)はオプショナル型に対してはダメ、という下のようなエラーメッセージが出る。
Cannot invoke initializer for type 'CGFloat' with an argument list of type '(Int?)'
//(2)だとコンパイルは通るけど下のような警告通り機能しない。
Cast from 'Int?' to unrelated type 'CGFloat' always fails
//(3)の三項演算子はちゃんと動くけど、、、見にくいぞ!数ヶ月後に見たら怒りが湧くだろう。
Swiftのことだから何かうまい書き方がありそうなものだけど、よくわからなかった、、、
ということでextensionでなんとかしてみた。
実はオプショナル型のにextensionを書いたのは初めてだ。こんな風に書くのね。
こうしておくとさっきのは↓このようにすっきり書ける。
func f(_ i: Int?) {
//let cgf = CGFloat(i)//—(1)
//let cgf = i as? CGFloat//—(2)
let cgf = (i != nil) ? CGFloat(i!) : nil//—(3)
…
}
//(1)はオプショナル型に対してはダメ、という下のようなエラーメッセージが出る。
Cannot invoke initializer for type 'CGFloat' with an argument list of type '(Int?)'
//(2)だとコンパイルは通るけど下のような警告通り機能しない。
Cast from 'Int?' to unrelated type 'CGFloat' always fails
//(3)の三項演算子はちゃんと動くけど、、、見にくいぞ!数ヶ月後に見たら怒りが湧くだろう。
Swiftのことだから何かうまい書き方がありそうなものだけど、よくわからなかった、、、
ということでextensionでなんとかしてみた。
実はオプショナル型のにextensionを書いたのは初めてだ。こんな風に書くのね。
extension Optional where Wrapped == Int {
var toOptCGFloat: CGFloat? {
if self == nil {
return nil
}
return CGFloat(self!)
}
}
こうしておくとさっきのは↓このようにすっきり書ける。
func f(_ i: Int?) {
let cgf = i.toOptCGFloat
…
}
スポンサーサイト