2016-05-26 7 views
1

私は一番最初の市民を使いたいですか?呼び出す関数を決定するにはSwiftをタイプします。Swiftのタイプのコンテキストタイプの推論2.2 +

func sf(v: [Float]) -> Float{ 
} 

func df(v: [Double]) -> Double { 
} 

func f<T: RealType>(seq ls: [T]) -> T { 
    if T.self == Float.self { 
    return sf(ls) // 1. where sf: Float -> Void 
    } else if T.self == Double.self { 
    return df(ls) // 2. where df : Double -> Void 
    } 
} 

タイプ推論システムでは、1つのブランチT == FloatとDoubleを別のブランチで認識できませんでしたか?

ここに欠落している機能、複雑な機能、またはバグはありますか?

編集

私のプロトタイプのための
typealias RealType = protocol<FloatingPointType, Hashable, Equatable, Comparable, FloatLiteralConvertible, SignedNumberType> 

が、プロトコル

+0

あなたのコードには 'RealType'がどのように定義されていますか? – Cristik

+0

RealTypeは現在のタイプアリアです。私はそれを追加するために私の質問を編集しました。 – jcnm

答えて

1

になりますあなたは、実行時の決定とジェネリックによって与えられた静的な解像度を結合しようとしているが、これは不可能です。

あなたは単にあなたが必要なものを得ることがFloatDoubleの両方にfをオーバーロードすることができます

func f(seq ls: [Float]) -> Float { 
    return sf(ls) // 1. where sf: Float -> Void 
} 

func f(seq ls: [Double]) -> Double { 
    return df(ls) // 2. where df : Double -> Void 
} 

しかし、あなたはRealTypeFloatまたは、Doubleよりもあなたが他の種類の上で使用することができ、一般的なプレースホルダになりたい場合は

protocol RealType { 
    static func processArray(v: [Self]) -> Self 
} 

extension Float: RealType { 
    static func processArray(v: [Float]) -> Float { 
     return sf(v) 
    } 
} 

extension Double: RealType { 
    static func processArray(v: [Double]) -> Double { 
     return df(v) 
    } 
} 

func sf(v: [Float]) -> Float{ 
    return 0 
} 

func df(v: [Double]) -> Double { 
    return 0 
} 

func f<T: RealType>(seq ls: [T]) -> T { 
    return T.processArray(ls) 
} 

これは、両方のタイプセーフティを提供します。これは、Swiftのメインの広告の1つです他のタイプに比べてfのサポートを追加する必要があるときはいつでも、そのタイプをRealTypeに準拠して宣言し、processArrayメソッドを実装する必要があります。

+0

ありがとう@Cristik。実行時に実行する分岐を決定するためにTypeを使用して簡潔な解決策を探していました。私は静的解析パス(抽象的な解釈を使用)はifブランチにあるので、条件式が真と評価されたことを暗示しているので、このコードを使用できると考えました。 これは不可能だと思われます。もしそうなら、あなたの答えを検証するつもりです。 – jcnm

関連する問題