2016-12-12 34 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

據我所知這是不可能的。 計算出的屬性仍然是一個只能屬於單一類型的屬性。

這就是說,也許你會通過擁有自己的這種類型的更好:

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 

如果你不想使用自己的類型,那麼你就必須堅持使用2種不同屬性。

+0

這是處理這種情況的好方法。 –

+1

順便說一句:通過符合'CustomStringConvertible'並將'stringValue'重命名爲'description',您將獲得更多好處。 –

0

不要這樣做!不要這樣做!!永遠不要這樣做。我沒有解釋這個想法有多糟糕的話。

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

(你應該看看是否符合CustomStringConvertible,但對於技術討論,在這裏如下...)

可以,但是實施enum包裝,每個包裝的情況下不同類型的關聯值(很像Optional<Int>包裝.none.some(Int))。

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

有了這個,你可以讓你的實例變量windDirection是兩個不同的包裝類型,這樣可以讓你期望的setter一個包裹類型,並在吸氣返回另一個包裝類型的包裝。例如:

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)'範圍內的任何值'N'(即北),即'180',這是向南的方向:) – dfri

+0

是的,我不要注意到這一點 –