2016-12-12 3 views
1

floatの範囲を文字列にマップしたいと思います。具体的には、例えば風の度合いを基調の方向に変換したいと思っています:220-> SW計算されたプロパティ:getとsetの間で異なるタイプ

Floatという宣言された計算されたプロパティを、get宣言で作成することができます。対応するStringを返品するにはこのようにして私はFloatと書くが、私はそれをStringと読む。

のような何か:

var windDirection: Float? { 
    get { 
     switch self.windDirection { 
     case 348.75..<11.25: 
      return "N" 
      break 
     ... 
     default: 
      break 
     } 
    } 
    set (newValue) { 
     self.windDirection = newValue 
    } 
} 

ない場合は、どのような可能性を私は同じ動作を生成することがありますか?

+1

私も、答えを見てみたいが、私は正直に答えははっきりと「いいえ」:-) – dasblinkenlight

+0

答えではないことを願っています** **いいえ、あなたは実際に 'ValueTransformer'を必要としています – vadian

答えて

2

私が知る限り、これは不可能です。 計算されたプロパティは、依然として単一の型でしかないプロパティです。あなたがあなた自身のタイプを使用したくない場合は、あなたが2つの異なるに固執する必要があります

struct WindDirection { 
    var degrees: Float 
    var stringValue: String { 
     get { 
      // compute the correct string here 
      return "\(degrees)" 
     } 
     set { 
      // compute the correct float value here 
      degrees = Float(newValue) ?? 0 
     } 

    } 
} 

var windDirection: WindDirection 

:おそらくあなたは、このために、独自の型を有することにより、より良いだろう、と述べた

プロパティ。

+0

これは、状況を処理するもっと良い方法です。 –

+1

BTW: 'CustomStringConvertible'に準拠し、' stringValue'の名前を 'description'に変更すると、より多くの利益を得ることができます。 –

0

Do not do this!こんなことしないで!!これまで決してこれを行うことはありません。私はこの考え方がどれほど悪いのかを説明する言葉はありません。

private var _windDirection: Float? 

var windDirection: Any? { 
    get { 
     guard let windDirection = _windDirection else { 
      return nil 
     } 

     switch windDirection { 
     case 348.75..<11.25: 
      return "N" 
     ... 
     default: 
      return nil 
     } 
    } 
    set (newValue) { 
     guard let windDirection = newValue as? Float else { 
      _windDirection = nil 
      return 
     } 

     _windDirection = windDirection 
    } 
} 
0

あなたは、しかしenumラッパーを実装することができ(...あなたはCustomStringConvertibleへの適合を見ている必要がありますが、技術的な議論のために、ここでは以下の)ここで各ケースラップ関連付けられた値の異なるタイプ(Optional<Int>.noneまたは.some(Int)とほぼ同じです)。これにより

enum WindDirection { 
    case asDegree(Float) 
    case asString(String) 
} 

、あなたのインスタンス変数windDirectionはあなたがセッターに1つのラップタイプを期待してゲッター内の別のラッパー型を返すことができるようになる二つの異なるラップタイプのラッパーであるとすることができます。例:

class Foo { 
    private var _windDirection: WindDirection 
    var windDirection: WindDirection { 
     get { 
      switch _windDirection { 
      case .asDegree(let angle): 
       switch(angle) { 
       case 348.75..<360.0, 0..<11.25: return .asString("N") 
       case 11.25..<33.75: return .asString("NE") 
       /* ... */ 
       case _ : return .asString("Not expected") 
       } 
      case _ : return .asString("Not expected") 
      } 
     } 
     set (newValue) { 
      if case .asDegree(_) = newValue { 
       _windDirection = newValue 
      } 
     } 
    } 

    init?(_ windDirection: WindDirection) { 
     guard case .asDegree(_) = windDirection else { return nil } 
     _windDirection = windDirection 
    } 
} 

使用例

// attempt initialization 
if let foo = Foo(.asDegree(11.0)) { 

    // getter 
    if case .asString(let windDirection) = foo.windDirection { 
     print(windDirection) // N 
    } 

    // setter 
    foo.windDirection = .asDegree(15.75) 

    // getter 
    if case .asString(let windDirection) = foo.windDirection { 
     print(windDirection) // NE 
    } 
} 
1

は、私はあなたがこの方法のように列挙型を使用することができるかもしれないと思います(ただし、ご使用のインスタンス・プロパティの呼び出しに包まれた関連する値のアンラップを処理する必要があります)

enum Wind { 
    case degree(Float) 
    case direction(String) 
} 

extension Wind { 

    init?(degree: Float) { 
     switch degree { 
     case 11.25..<385: 
      self = .direction("N") 
     default: 
      return nil 
     } 
    } 

} 

let wind = Wind(degree: 100) // Result is direction("N") 
+0

'11.25 .. <385'とのパターンマッチングは、' [11.25、385.0] 'の範囲内の値、つまり南である' 180'の値に対して 'N'(北)を返します。 – dfri

+0

ええ、私それに気付かないでください –

関連する問題