2016-12-02 18 views
5

स्विफ्ट 3 में, मैंने एक कस्टम ऑपरेटर prefix operator § लिखा है जिसे मैं String लेते हुए एक विधि में उपयोग करता हूं क्योंकि LocalizedString स्ट्रक्चर (मूल्य कुंजी और मूल्य)।स्विफ्ट: डॉट ("।") के संबंध में कस्टम ऑपरेटर के लिए प्राथमिकता

public prefix func §(key: String) -> LocalizedString { 
    return LocalizedString(key: key) 
} 

public struct LocalizedString { 
    public var key: String 
    public var value: String 

    public init(key: String) { 
     let translated = translate(using: key) // assume we have this 
     self.key = key 
     self.value = translated ?? "!!\(key)!!" 
    } 
} 

(हाँ, मैं भयानक L10n enum in SwiftGen के बारे में पता है, लेकिन हम अपने बैकएंड से हमारे तार डाउनलोड कर रहे हैं, और इस सवाल यह है कि कस्टम ऑपरेटरों के साथ काम करने के लिए के बारे में अधिक है)

लेकिन अगर हम मिल करना चाहते हैं § ऑपरेटर का परिणाम से अनुवादित मूल्य (यानी जिसके परिणामस्वरूप LocalizedString से संपत्ति value)

let translation = §"MyKey".value // Compile error "Value of type 'String' has no member 'value'" 

हम निश्चित आसानी से इसे wraping द्वारा इस संकलन त्रुटि को ठीक कर सकते हैं कंस्ट्रैसिस (§"MyKey").value में। लेकिन अगर ऐसा नहीं करना चाहते हैं। 'डॉट' शाब्दिक के संबंध में कस्टम ऑपरेटरों के लिए प्राथमिकता निर्धारित करना संभव है?

हाँ मुझे पता है कि केवल इन्फ़िक्स ऑपरेटरों पूर्वता घोषित कर सकता है, लेकिन यह समझ में किसी भी तरह क्रम में प्राथमिकता दी के साथ काम करने को प्राप्त करने के जो मैं चाहता होगा:

precedencegroup Localization { higherThan: DotPrecedence } // There is no such group as "Dot" 
prefix operator §: Localization 

चिह्नित करने के लिए है कि स्विफ्ट संकलक पहले करना चाहिए §"MyKey" का मूल्यांकन करें और समझें कि एक स्ट्रिंग नहीं है, लेकिन वास्तव में LocalizedString (संरचना)।

असंभव लगता है कि यह असंभव होगा? मैं क्या खो रहा हूँ?

+0

मैंने कोशिश की लेकिन मुझे कोई रास्ता नहीं मिला, शायद हमें एक रडार दर्ज करने की आवश्यकता है, लेकिन अगर मैं इसे वास्तव में एक बग के रूप में बुलाया जा सकता हूं तो मैं उलझन में हूं। –

उत्तर

5

. मानक लाइब्रेरी में परिभाषित अन्य सभी की तरह एक ऑपरेटर नहीं है, यह इसके बजाय संकलक द्वारा प्रदान किया जाता है। इसके लिए व्याकरण Explicit Member Expressions है।

. की तुलना में अधिक प्राथमिकता होने के कारण संकलक आपको ऐसा करने में सक्षम नहीं करता है, क्योंकि यह एक मौलिक उपयोग केस है। कल्पना कीजिए कि आप अगर संकलक ऐसी बात सक्षम क्या कर सकते हैं:

(-"Test").characters.count // func -(s: String) -> String 
(-("Test".characters)).count // func -(s: String.CharacterView) -> String.CharacterView 
-("Test".characters.count) // func -(s: Int) -> Int 

कौन सा होगा

:

-"Test".characters.count 

आप . तुलना में एक उच्च पूर्वता हो सकता था, तो संकलक सभी संभावनाओं की जांच करने के लिए किया

  • संभावित रूप से संकलन समय को बढ़ाएं
  • संदिग्ध रहें
  • संभवतः जोड़ने भार के

मैं तुम्हें क्या सुझाव एक नया ऑपरेटर के साथ विचार को त्याग करना पर मौजूदा कोड का व्यवहार बदलने के लिए, यह केवल एक ही अस्पष्ट में कुछ विशिष्ट व्यवहार कुचलने से अधिक संज्ञानात्मक लोड जोड़ने जा रहा है चरित्र।यह कैसे मैं यह कर होता है:

extension String { 
    var translatedString : String { 
     return translate(using: self) 
    } 
} 

"MyKey".localizedString 

या आप उपयोग करना चाहते हैं अपने LocalizedString:

extension String { 
    var localized : LocalizedString { 
     return LocalizedString(key: self) 
    } 
} 

"MyKey".localized.value 

इन संस्करणों और अधिक व्यापक हैं।

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