2014-10-24 8 views
6

मैं विभिन्न इकाइयों के साथ काम कर रहा हूँ, यानी distance, altitude, speed, volume, आदिविस्तार प्रकार उपनाम तेज

मेरा लक्ष्य, अनुप्रयोग में उन्हें फ़ॉर्मेट करने के लिए उदाहरण के लिए एक सुंदर, अनोखा तरीका है myValue.formatted बुला:

let mySpeed: Speed = 180 
println(mySpeed.formatted) // 5.0 km/h 

let myAltitude: Altitude = 4000 
println(myAltitude.formatted) // 4000 m 

मैंने सोचा था कि इस प्रकार के उपनाम का उपयोग कर के लिए एक अच्छा मामला था।

typealias Distance = Float 
typealias Altitude = Float 
typealias Speed = Float 

formatted संपत्ति के लिए, मैं प्रकार Float के extension साथ करने की कोशिश की:

extension Float { 
    var formatted: String { 
     get { 
      switch self { 
      case is Altitude: 
       return "\(self) m" 
      case is Speed: 
       return "\(self * 3.6) km/h" 
      default: 
       return "\(self)" 
      } 
     } 
    } 
} 

लेकिन संकलक का कहना है कि मेरी case ब्लॉक हमेशा true हैं।

तो मैं एक प्रकार का विस्तार करने की कोशिश की:

extension Speed { 
    var formatted: String { 
    return "\(self * 3.6) km/h" 
    } 
} 
extension Altitude { 
    var formatted: String { 
    return "\(self) m" 
    } 
} 

संकलक अब स्पष्ट रूप से कहा गया है 'स्वरूपित'

ठीक की अमान्य पुन: घोषणा, अब यह कैसे प्रकार उपनाम काम स्पष्ट है। लेकिन मैं अपने .formatted संपत्ति को स्विफ्ट में विभिन्न प्रकार के फ्लोट्स के लिए कैसे प्राप्त करूं?

उत्तर

5

typealias बस बदलने के लिए या प्रकार का नाम बदलने के इस तरह संकलक अपने कोड को देखता है। यह आपके लिए एक और उपयोगकर्ता प्रकार नहीं बनाता है। आप वास्तव में , Altitude के लिए Float का विस्तार कर रहे हैं।

आप Literals प्रकारों के अनुरूप अपने कस्टम स्ट्रक्चर में पास कर सकते हैं।

let mySpeed: Speed = 180 

FloatLiteralConvertible और IntegerLiteralConvertible आप ही कार्यक्षमता दे देंगे आप चाहते हैं और आप सीधे अपने कस्टम struct types को मान निर्दिष्ट के रूप में आप Float

struct Speed: FloatLiteralConvertible,IntegerLiteralConvertible { 

    var distance:Float 
    init(floatLiteral value: Float) { 
     distance = value 
    } 

    init(integerLiteral value: Int){ 
     distance = Float(value) 
    } 

    var formatted: String { 
     return "\(distance * 3.6) km/h" 
    } 
} 

let mySpeed: Speed = 180.0 
println(mySpeed.formatted) // 5.0 km/h 
+0

यह वास्तव में बहुत दिलचस्प है। यह थोड़ा निराशाजनक है कि मैं 'फ्लोट वार को स्पीड' नहीं डाल सकता, यानी 'as' कीवर्ड का उपयोग कर रहा हूं। टाइप उपनाम इस तरह से सुरुचिपूर्ण था। – gpbl

+0

@crumblenaut आप सही हैं। स्पीड अब 'फ्लोट 'नहीं है। यह उपयोगकर्ता परिभाषित कस्टम प्रकार है।आप एक फंक्शन के साथ 'फ़्लोट' को एक प्रकार से प्रारूपित कर सकते हैं। अगर आप वास्तव में ऐसा करना चाहते हैं तो 'प्रारूप स्पीड', एक्सटेंशन में प्रारूप डिस्टेंस का उपयोग करें। – codester

1

Distance, Altitude, और Speed हमेशा एक ही प्रकार है - Float और एक ही formatted संपत्ति को साझा करें।

extension Float { 
    var formatted: String { 
     get { 
      switch self { 
      case is Float: 
       return "\(self) m" 
      case is Float: 
       return "\(self * 3.6) km/h" 
      default: 
       return "\(self)" 
      } 
     } 
    } 
} 

मुझे लगता है कि आप अपनी कार्यक्षमता के लिए छोटे रैपर बनाने की जरूरत:

struct Distance { 
    var value: Float 
    var formatted: String { 
     return "\(value) m" 
    } 

    init(_ value: Float) { 
     self.value = value 
    } 
} 

let myDistance = Distance(123) 
myDistance.formatted 
+0

अंतर्दृष्टि के लिए धन्यवाद प्रदान कर सकते हैं। अफसोस की बात यह है कि मैं नहीं लिख सकता: 'मेरी स्पीड: स्पीड = 30'। मुझे लगता है कि मैं एक और "स्वरूपण" समाधान के साथ जाऊंगा। – gpbl

+0

आप इस दृष्टिकोण के साथ 'मेरी स्पीड = स्पीड (30.0) 'दे सकते हैं। – Kirsteins

+0

@crumblenaut इस [आलेख] (http://nshipster.com/swift-literal-convertible/) को देखें, शाब्दिक असाइनमेंट को कार्यान्वित करने के तरीके को जानने के लिए – Antonio

संबंधित मुद्दे