LoginSignup
17
12

More than 5 years have passed since last update.

init の名は。

Last updated at Posted at 2017-06-12

前書き(という名の無駄話

タイトル結構悩んだ。ぶっちゃけシンプルにまとめられそうなタイトル思いつかなかったのでネタに走ろうと思った。そして「init の形」とどっち選ぶか悩んだけど最終的に「ネタのわかりやすさ」と「やってることのわかりづらさ」でこっちの名前にしました。反省はしていない。

本編

とあることやろうとしてて、「そういえば init って名前の static func 作ったらどうなるんだろ?」っと思って、こんな闇深いソースを作ってみたら意外とちゃんと(?)動いた。

extension Int {
    static func `init`(float: Float) -> Float {
        return float
    }
}

let float = Int(float: 3.14)
print(float) // 3.14

やろうとしてること読んでわかるよね?Intextensioninit って名前の返り値が Floatstatic func 作って、それをそのまま Int() といういかにも Int のイニシャライザーを呼んでる形の呼び出しを書いたらちゃんと Float で生成されたという黒魔術。「ちゃんと」っていうとなんか変だけど。ちなみに今日ツイッターで呟いたら思ったより拡散されて多分みんなも闇だと感じてるんじゃないかと。なるほど init って名前の static func 作っちゃうとそれが「イニシャライザー」(?)として使えるんだね。

一応説明

いかにも闇深そうなコードを面白半分で紹介しましたが、もちろん本来の意図はこんな闇深いことをやりたかったわけではありません。きちんとした理由があるのです。

最近この記事に刺激されて、確かに衝突するのも回避したいし何よりこの書き方がとても好きで自作のフレームワークにもこういう書き方に対応したいなぁと思いつつ、Eltaso の修正にかかってるのですが、もともと作ってた CGPoint(point: CGFloat) のイニシャライザーがどうすればいいんだろ、自分自身の型とは違う型のイニシャライザーって作れないのかな?まあ最悪作れなくても .init(point: CGFloat) で書ければいいかな、ってノリでとりあえず static func init を作ってみたらそれがちゃんとうまく行ったんですね。そこでふっと思ったんですよ。じゃあ (point: CGFloat) って使えないのかな?って。そしたら Playground で書いてみたら動いた。

ちなみに今改造中のコードはこんな感じです:

public protocol EltasoCompatible {
    associatedtype Eltaso
    var eltaso: EltasoContainer<Self> { get }
}

extension EltasoCompatible {
    public var eltaso: EltasoContainer<Self> {
        return EltasoContainer(body: self)
    }
}

public struct EltasoContainer<Containee> {
    public let body: Containee
}

extension CGPoint: EltasoCompatible {
    public typealias Eltaso = EltasoContainer<CGPoint>
}

extension EltasoContainer where Containee == CGPoint {

    public static func `init`(point: CGFloat) -> CGPoint {
        return CGPoint(x: point, y: point)
    }

}

let point = CGPoint.Eltaso.init(point: 3.14)
print(point) //(3.14, 3.14)

ね?綺麗でしょ?(自画自賛

17
12
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
12