個人的にGLSLやOpenCLなんかのswizzeringが好きで、オレオレのベクタ型にはそれっぽいのを必ず用意してたりします。
SwiftはずーっとTLの狼狽を眺めてばかりでやり過ごしてたのですが、このswizzeringを一番そっくりに使えそうなのに気づいてすこし格闘してました。最悪の場合、type毎に、別の言語でソースコード生成してしまおうかとボンヤリしてたら、ふっと、「もしかして?」みたいな感じで、protocolにextensionを書いてみたところ、ばっちり動いてくれました。
Swift情報に疎く、ほぼSwift初心者なので、ネットに頼らず自力で発見できたことが嬉しくて、記録として残そうと思った次第です。
CGPointだけだと過剰ですな。でも、3要素や4要素あるベクタが複数あるとき、あるいは色々試したいとき、これからは楽できそう。
protocol Component2Swizzering { typealias ItemType typealias Component2Type var x: ItemType { get set } var y: ItemType { get set } func C2_INIT( x x: ItemType, y: ItemType ) -> Component2Type func X_C2( c : Component2Type ) -> ItemType func Y_C2( c : Component2Type ) -> ItemType }
extension Component2Swizzering { var xy : Component2Type { get { return C2_INIT( x: x, y: y ) } set(p) { x = X_C2(p); y = Y_C2(p) } } var yx : Component2Type { get { return C2_INIT( x: y, y: x ) } set(p) { x = Y_C2(p); y = X_C2(p) } } var xx : Component2Type { get { return C2_INIT( x: x, y: x ) } } var yy : Component2Type { get { return C2_INIT( x: y, y: y ) } } }
extension CGPoint : Component2Swizzering{ typealias Component2Type = CGPoint func C2_INIT(x x:ItemType,y:ItemType) -> Component2Type { return CGPoint( x: x, y: y ) } func X_C2(c : Component2Type ) -> ItemType { return c.x } func Y_C2(c : Component2Type ) -> ItemType { return c.y } }
var point : CGPoint = CGPointMake(10, 20) // point変数に(10.0,20.0)が入ってる print( point.yz ) // だけど(20.0,10.0) と表示される