2015-08-28 4 views
15

मैं स्विफ्ट के लिए नया हूँ और सिर्फ दस्तावेज में यह भर में आया था:एनम्स ने गुणों की गणना क्यों की है लेकिन स्विफ्ट में संपत्तियों को संग्रहीत नहीं किया है?

गणना गुण कक्षाएं, संरचना, और enumerations द्वारा प्रदान की जाती हैं। संग्रहीत गुण केवल कक्षाओं और संरचनाओं द्वारा प्रदान किए जाते हैं।

वह क्यों है? संग्रहीत गुणों जैसे enum काम के लिए संबंधित मूल्य करते हैं? ऐसा लगता है कि उन्होंने शुरुआत में संपत्तियों को संग्रहित किया था - Why no stored type properties for classes in swift?

उत्तर

6

enum रों करते संग्रहीत किया है प्रकार गुण - यानी, static गुण। उन्होंने उदाहरण गुणों को संग्रहीत नहीं किया है। मुझे नहीं पता कि तकनीकी कारण है कि संग्रहित उदाहरण गुण enum एस के लिए क्यों उपलब्ध नहीं हैं। यदि आप "क्यों" के लिए तकनीकी उत्तर चाहते हैं तो आपको देव फोरम पर अपना प्रश्न पूछना पड़ सकता है।

आपके प्रश्न में आप पूछते हैं कि संबंधित मान संग्रहीत गुणों की तरह काम करते हैं या नहीं। वास्तव में, वे struct एस और class es के लिए संग्रहीत गुणों की तुलना में अधिक लचीला (कुछ तरीकों से) हैं। प्रत्येक caseenum में इसका अपना विशिष्ट डेटा सेट हो सकता है जो इसके साथ जुड़ा हुआ है। संग्रहीत गुणों का एक सेट होने के बजाय जो सभी case एस पर लागू होते हैं, आप प्रत्येक case के लिए संग्रहीत गुणों को वैयक्तिकृत करते हैं।

0

एक enum को एक संरचित डेटा प्रकार के रूप में माना जाता है जिसे बिना किसी स्ट्रिंग या इंट को आपके कोड में बदलने के लिए संशोधित किया जा सकता है और एक enum के साथ हम कभी भी नहीं कर सकते एक ही चीज़ को एक से अधिक बार बदलने के बारे में चिंता करें। उदाहरण के लिए ड्रॉपडाउन मेनू:

enum DropDownMenuOptions: String { 
    case MenuOptionOne 
    case MenuOptionTwo 
    case MenuOptionThree 
} 

संग्रहीत गुणों के साथ आप आवश्यक जानकारी को पूर्ववत कर सकते हैं और अपने मुख्य कार्य में कोड को कम कर सकते हैं। सर्वश्रेष्ठ उदाहरण उदाहरण के लिए रेक्ट के आकार की गणना है:

struct Point { 
    var x = 0.0, y = 0.0 
} 
struct Size { 
    var width = 0.0, height = 0.0 
} 
struct Rect { 
    var origin = Point() 
    var size = Size() 
    var center: Point { 
     get { 
      let centerX = origin.x + (size.width/2) 
      let centerY = origin.y + (size.height/2) 
      return Point(x: centerX, y: centerY) 
     } 
     set(newCenter) { 
      origin.x = newCenter.x - (size.width/2) 
      origin.y = newCenter.y - (size.height/2) 
     } 
    } 
} 

var square = Rect(origin: Point(x: 0.0, y: 0.0), 
    size: Size(width: 10.0, height: 10.0)) 
+2

लेकिन Enums था संग्रहीत गुण प्रारंभ में - http: // stackoverflow।कॉम/प्रश्न/24029581/क्यों-नहीं-संग्रहीत-प्रकार-गुण-वर्ग-में-स्विफ्ट –

+0

अच्छी तरह से enum डिफ़ॉल्ट रूप से संरचना है ताकि आप इसे बढ़ा सकें और कुछ फ़ंक्शन कर सकें जो ऐसा कर सकता है लेकिन मुझे नहीं दिखाई देता इसके लिए एक कारण ... वे स्थिर, ज्ञात, गणना की गई संरचना के लिए उपयोग किए जाते हैं और उनका उपयोग करने का सबसे अच्छा तरीका इस तरह है ... –

2

मैं उन संपत्तियों को संग्रहीत करने के लिए एक छोटी सी चाल का उपयोग करता हूं जो प्रारंभिकरण पर एक्सेसिबल नहीं हैं।

पहले, मैं एक वर्ग Future जो भविष्य में संगृहीत संपत्ति स्टोर करेगा बनाने के लिए:

enum Sample { 
    case Test(future: Future<String>) 
} 

का दृष्टांत:

let enumTest = Sample.Test(future: Future()) 

class Future<T> { 
    var value: T? 
    init(value: T? = nil) { 
     self.value = value 
    } 
} 

तब मैं अपने enum बनाने बाद में कोड में:

switch enumTest { 
    case let .Test(future): 
    future.value = "Foo" 
} 

और बाद में, आप मूल्य पहुँच सकते हैं:

switch enumTest { 
    case let .Test(future): 
    // it will print Optional("Foo") 
    print("\(future.value)") 
} 

यह कुछ आप का दुरुपयोग नहीं करना चाहिए है, लेकिन यह कुछ मामलों में सहायक हो सकता है।

उम्मीद है कि यह मदद करता है।

+0

क्यों स्ट्रिंग या सीधे एनम के संबंधित मूल्य में स्टोर न करें? –

6

संग्रहित इंस्टेंस गुणों को अनुमति देने वाले एम्स एक डिज़ाइन विकल्प नहीं है। संग्रहीत उदाहरण गुणों के साथ enum होने के कारण यह एक संरचना (enum superpowers के साथ) बनाता है, लेकिन बस परिप्रेक्ष्य से अब enums प्रकार गुणक की तरह कार्य करेगा। मूल रूप से विचार करना

enum Set1 { 
    case a 
    case b 
    case c 
} 

enum Times { 
    case x 
    case y 

    var k: Set1 
} 

क्या यह वास्तव में है कि enum Times हमें Set1 और Set2 6 अलग मामलों में जिसके परिणामस्वरूप से तत्वों के किसी भी संयोजन होने की अनुमति देता है मतलब है, लेकिन रुकिए, हम जानते हैं कि वास्तव में यह एक टपल प्रकार का एक उद्देश्य है (Set1, Set2) की तरह, जहां Times रूप

typealias Times = (Set1, Set2) 

घोषित किया जा सकता है कि मैं इस पूर्व के मामले की अनुमति नहीं दे के लिए एक उचित तर्क के रूप में कार्य करता है उम्मीद है।

कहा जा रहा है, तेज enums इस प्रकार हमें घोषित करने के लिए क्या कार्यात्मक प्रोग्रामिंग में भेदभाव संघ के रूप में जाना जाता है की अनुमति देता है हमें एक मामले साथ एक मनमाना एन-टपल जोड़ अनुमति देते हैं,। यदि आप चाहें तो मामले से जुड़ी एक संग्रहीत संपत्ति को कॉल करें। प्रकार के दृष्टिकोण से अब यह प्रकार योजक के रूप में कार्य करता है।

enum Add { 
    case lhs(Set1) 
    case rhs(Set2) 
} 

अब हमारे पास 5 अलग-अलग मामले हैं। अब हम 2-tuples संग्रहीत करते हैं:

enum AddTimes { 
    case lhs(Set1, Set2) 
    case rhs(Set3, Set4) 
} 

अब हम मूल रूप से गुणा का योग (SET1 * SET2 + set3 * SET4) है। यह पैटर्न मिलान की बात आती है जब यह एक बहुत शक्तिशाली उपकरण है।

हाउवर, कुछ असली मामले मौजूद हैं जब आप वास्तव में enum के अंदर संग्रहीत संपत्ति के रूप का अनुकरण करना चाहते हैं। इस पर विचार करें:

public enum Service { 
    case registerNewUser(username: String, password: String, language: String) 
    case login(username: String, password: String, deviceTokenº: String?) 
    case logout(sessionToken: String) 
    case sendForgotPassword(email: String) 
} 

(तरह ढांचे में मोया) बाकी अंतिमबिंदुओं परिभाषित करने के लिए आप एक अनुरोध आप

MoyaProvider<Service>.request(.sendForgotPassword(email: "[email protected]")) 

की तरह कुछ करना होगा सक्रिय करना चाहते हैं जब एक कथात्मक तरीका है लेकिन अब आप कल्पना आप उत्पादन और परीक्षण सर्वर के बीच अंतर करना चाहते हैं। आप प्रत्येक मामले में एक और टपल तत्व के रूप में एक सर्वर जोड़ते हैं:

case forgotPassword(sessionToken: String, serverBaseURLString: String) 

इस के बाद से आप मूल रूप से प्रत्येक टपल अनुरोध पैरामीटर स्टोर करने के लिए करना चाहते हैं, एक गलत अर्थ विज्ञान है हो जाएगा, लेकिन अब यह एक सर्वर आधार पते संग्रहीत करता है।

इस तरह की चीजों से बचने के लिए हम वास्तव में निम्नलिखित तरीके से हमारे प्रकार को पैरामीटर कर सकते हैं। इसके बजाय सर्वर के रूप में परिभाषित किया जा रहा है कहते हैं:

enum Server: String { 
    case production = "https://service.info" 
    case test = "http://test.service.info" 
} 

हम की तरह प्रत्येक मामले के लिए अलग प्रकार के साथ परिभाषित कर सकते हैं:

public struct ProductionServer: ServerType { 
    public static var baseURLString: String { return "https://service.info" } 
} 
public struct TestServer: ServerType { 
    public static var baseURLString: String { return "http://test.service.info" } 
} 
public protocol ServerType { 
    static var baseURLString: String { get } 
} 

और अंत के रूप में हमारे ServiceType parametrize

public enum Service<T> where T: ServerType { 
    case registerNewUser(username: String, password: String, language: String) 
    case login(username: String, password: String, deviceTokenº: String?) 
    case logout(sessionToken: String) 
    case sendForgotPassword(email: String) 

    var serverURL: URL { 
     return T.baseURL 
    } 
} 

public typealias ProdutionService = Service<ProductionServer> 
public typealias TestService = Service<TestServer> 
संबंधित मुद्दे

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