2016-12-12 4 views
1

Ich möchte Bereiche von Float zu Zeichenfolgen zuordnen. In Details würde Ich mag den Grad Windrichtung beispielsweise konvertieren, in der entsprechenden Zeichenfolge mit der Richtung Kardinal: 220 -> SWBerechnete Eigenschaft: verschiedene Typen zwischen get und set

Es ist möglich, eine berechnete Eigenschaft des Typs mit der benutzerdefinierten get Erklärung Float erklärt zu schaffen, in um die entsprechende String zurückzugeben? Auf diese Weise werde ich es als Float schreiben, aber ich werde es als String lesen.

Etwas wie:

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

Wenn nicht, welche Möglichkeiten habe ich das gleiche Verhalten produzieren?

+1

ich würde gerne die Antwort zu sehen, auch, aber ich hoffe wirklich, dass die Antwort eine klare „nein“ ist :-) – dasblinkenlight

+0

die Antwort ** ** ist nicht, was Sie brauchen eigentlich ein 'ValueTransformer' – vadian

Antwort

2

Soweit ich weiß, ist das unmöglich. Eine berechnete Eigenschaft ist immer noch eine Eigenschaft, die nur von einem einzigen Typ sein kann.

das gesagt ist, vielleicht können Sie Ihre eigene Art für diese, indem er besser sein würde:

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 

Wenn Sie wollen nicht Ihre eigene Art verwenden, dann werden Sie mit 2 verschiedenen bleiben müssen Eigenschaften.

+0

Dies ist ein viel besserer Weg, um mit der Situation umzugehen. –

+1

BTW: Sie würden mehr profitieren, indem Sie 'CustomStringConvertible' anpassen und' stringValue' in 'description' umbenennen. –

0

Tun Sie das nicht! Mach das nicht!! Tue das niemals. Ich habe nicht die Worte, um zu erklären, wie schlimm eine Idee ist.

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

(Sie sollten einen Blick auf die Konformität mit CustomStringConvertible, aber für die technische Diskussion, hier folgt ...)

Sie könnte jedoch eine enum Wrapper implementieren, wo jeweils Wraps verschiedene Arten von assoziierten Werten (ähnlich wie Optional<Int> wraps .none oder .some(Int)).

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

Damit können Sie Ihre Instanz Variable windDirection seine ein Wrapper von zwei verschiedenen Arten gewickelt lassen, die Ihnen ungeöffneten Typen in dem Setter zu erwarten und zurückzukehren und eine anderen Wrapper Typen in dem Getter erlauben würden. ZB:

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 
    } 
} 

Beispiel zur Nutzung (Sie müssten die Abwickeln des gewickelten zugehörigen Wert bei Aufruf an die Instanz Eigenschaft zu handhaben, aber)

// 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

Ich denke, vielleicht haben Sie ENUM wie auf diese Weise verwenden können

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

Beachten Sie, dass ein Mustervergleich mit '11.25 .. <385' 'N' (Norden) für jeden Wert im Bereich' [11.25, 385.0) 'ergibt, dh' 180', also weit nach Süden :) – dfri

+0

Yeah, I merke das nicht –

Verwandte Themen