2016-06-21 17 views
2

私はスウィフトにおける2Dベクトル構造体を実装しています:Swiftで一般的な変換イニシャライザを実装する方法は?

public struct Vec2<T: Numeric> { 
    public let x: T 
    public let y: T 

    public init(_ x: T, _ y: T) { 
     self.x = x; 
     self.y = y; 
    } 

    // ... 
} 

public protocol Numeric: Equatable { 
    // ... 
} 

extension Int: Numeric {} 
extension Double: Numeric {} 
extension Float: Numeric {} 

このコードはコンパイルされます。ここでは、変換初期設定子を追加して、 Vec2<Int>からVec2<Float>までである。私はVec2にこれを追加しました:

public init<T2: Numeric>(_ other: Vec2<T2>) { 
     self.x = T(other.x) 
     self.y = T(other.y) 
    } 

Numericプロトコルに必要な初期化子:しかし

init(_: Int) 
    init(_: Double) 
    init(_: Float) 

を、これは私が解決することができないんだエラーが発生します。

はできません型 'T'の初期化子を '(T2)型'の引数リストで呼び出す

overlo (Int)、(Double)、(Float)

どのようなアイデアですか?

+0

問題は(デュープ質問へのわずかに異なるが、私はそれが別の答えを保証わからないんだけど)あなたのプロトコルは、そのすべての具体的なタイプがあることを保証することはできませんということです'Numeric'に準拠しているかどうかは、あなたが要件に列挙した初期化子によって処理されます。したがって、すべての型が独自の変換ロジックを実装することを保証するために、プロトコルに「シャドー」関数要件を追加するようなことを行う必要があります。これは上記のリンクされた質問に対する私の答えです。 – Hamish

+0

@ originaluser2ありがとう、それはそれを解決! – emlai

+0

お手伝いします:) – Hamish

答えて

1

_asOther「影」関数の解答がhereで示されました。念のために誰もが興味を持って、ここで最終的なコードです:

public struct Vec2<T: Numeric> { 
    public let x: T 
    public let y: T 

    public init(_ x: T, _ y: T) { 
     self.x = x; 
     self.y = y; 
    } 

    public init<T2: Numeric>(_ other: Vec2<T2>) { 
     self.x = other.x._asOther() 
     self.y = other.y._asOther() 
    } 

    // ... 
} 

public protocol Numeric: Equatable { 
    init(_: Int) 
    init(_: Double) 
    init(_: Float) 
    func _asOther<T: Numeric>() -> T 
    // ... 
} 

extension Int: Numeric { 
    public func _asOther<T: Numeric>() -> T { return T(self) } 
} 

extension Double: Numeric { 
    public func _asOther<T: Numeric>() -> T { return T(self) } 
} 

extension Float: Numeric { 
    public func _asOther<T: Numeric>() -> T { return T(self) } 
} 
関連する問題