2014-11-13 5 views
5

में Set.addSequence को कार्यान्वित करना मैंने स्विफ्ट में एक सेट लागू किया है जो शब्दकोश कुंजी का उपयोग करता है। मैं एक addAll (अनुक्रम) विधि को कार्यान्वित करना चाहता हूं जो सेट में तत्वों पर कोई अनुक्रम प्रकार लेता है, लेकिन मुझे एक त्रुटि मिल रही है जो समझ में नहीं आता है। यहां मेरा कोडस्विफ्ट

struct Set<Element: Hashable> { 
    var hash = [Element: Bool]() 

    init(elements: [Element] = []) { 
     for element in elements { 
      self.hash[element] = true 
     } 
    } 

    var array: [Element] { 
     return hash.keys.array 
    } 

    func contains(element: Element) -> Bool { 
     return hash[element] ?? false 
    } 

    mutating func add(element: Element) { 
     hash[element] = true 
    } 

    mutating func add(array: [Element]) { 
     for element in array { 
      hash[element] = true 
     } 
    } 

    mutating func add<S : SequenceType where S.Generator.Element == Element>(sequence: S) { 
     for element in sequence { // Error here: "Cannot convert the expression's type 'S' to type 'S' 
      hash[element] = true 
     } 
    } 

    mutating func remove(element: Element) { 
     hash[element] = nil 
    } 
} 

मुझे यह त्रुटि XCode 6.1 और 6.0.1 में मिल रही है।

मैं ऐरे की विस्तार विधि के अर्थशास्त्र का पालन करना चाहता था, लेकिन उस प्रकार का हस्ताक्षर मेरे लिए भी संकलित नहीं होता है।

क्या मैं कुछ गलत कर रहा हूं, या क्या मुझे रडार दर्ज करना चाहिए?

संपादित: सिर्फ https://github.com/robrix/Set/blob/master/Set/Set.swift पाया, इसलिए ऐसा करना है जो:

public mutating func extend<S : SequenceType where S.Generator.Element == Element>(sequence: S) { 
    // Note that this should just be for each in sequence; this is working around a compiler crasher. 
    for each in [Element](sequence) { 
     insert(each) 
    } 
} 

हालांकि, कि सिर्फ sequence एक Array है, जो एक तरह से पूरी तरह SequenceType के प्रयोजन के धरा में बदल देता है।

उत्तर

4

अद्यतन: यह स्विफ्ट 1.2 (एक्सकोड 6.3 बीटा 3) में तय किया गया है, बिना किसी त्रुटि के प्रश्न संकलित से मूल कोड। (इसके अलावा, परिभाषित करने एक कस्टम सेट प्रकार आवश्यक नहीं है अब और क्योंकि स्विफ्ट 1.2 एक देशी Set प्रकार में निर्मित किया गया है।)


पुराना जवाब: यह मेरे लिए एक बग की तरह दिखता है, लेकिन शायद किसी को इसे समझा सकते हैं।

संभावित समाधानों:

  • स्पष्ट SequenceOf<Element> में कनवर्ट sequence तर्क:

    mutating func add<S : SequenceType where S.Generator.Element == Element>(sequence: S) { 
        for element in SequenceOf<Element>(sequence) { 
         hash[element] = true 
        } 
    } 
    
  • (https://stackoverflow.com/a/27181111/1187415 में के रूप में) की जगह के लिए लूप थोड़ी देर के पाश की next() का उपयोग करके अनुक्रम जनरेटर, और एनोटेट टाइप करें element : Element:

    0 के साथ स्पष्ट रूप से तत्व
    mutating func add<S : SequenceType where S.Generator.Element == Element>(sequence: S) { 
        var gen = sequence.generate() 
        while let element : Element = gen.next() { 
         hash[element] = true 
        } 
    } 
    
  • ("Creating a Set Type in Swift" से) map का उपयोग करें:

    mutating func add<S : SequenceType where S.Generator.Element == Element>(sequence: S) { 
        map(sequence) { 
         self.hash[$0] = true 
        } 
    } 
    
+0

मैं मानता हूं कि यह एक बग है। क्या किसी ने इसकी रिपोर्ट की? धन्यवाद – drasto

+1

@drasto: मुझे नहीं पता। लेकिन किसी भी मामले में, यदि आप इस समस्या से प्रभावित हैं, तो अपनी खुद की बग रिपोर्ट जमा करें। –

+0

'मानचित्र' का उपयोग करना सबसे अच्छा कामकाज जैसा लगता है। मुझे लगता है कि मुख्य समस्या यह है कि 'मानचित्र' वास्तव में दुष्प्रभावों की अनुमति नहीं देनी चाहिए। – bart

3
सबसे अच्छा मैं नक्शा समाधान है कि मार्टिन भी उत्पादन किया था के साथ आ सकता है

mutating func add<S : SequenceType where S.Generator.Element == Element>(sequence: S) { 
    var generator = sequence.generate() 
    while let item = generator.next() { 
     self.hash[item] = true 
    } 
} 

generator.next() में उत्पादन अभी तक एक और त्रुटि संदेश: दिलचस्प बात यह मैन्युअल रूप पाश के लिए विस्तार हो रहा

Cannot convert the expression's type '()' to type 'Self.Element??' 

यह हो सकता है कुछ और अधिक नक्शे के बजाय कम करने, कि के रूप में नहीं है का उपयोग करने के इष्टतम हो त्यागने के लिए एक सरणी बनाएं:

mutating func add<S : SequenceType where S.Generator.Element == Element>(sequence: S) { 
    reduce(sequence,()) { 
     self.hash[$1] = true 
    } 
} 
+0

आपका पहला संस्करण 'जबकि आइटम: एलिमेंट = जेनरेटर.नेक्स्ट() {..} 'के साथ काम कर सकता है। 'कम() 'के साथ अच्छा विचार! (लेकिन नक्शा/कम दोनों ही हैंक्स, केवल 'इन' के लिए एक सरल 'काम करना चाहिए।) –

+0

वह त्रुटि संदेश बग में एक विंडो है -' के लिए ... वास्तव में 'केवल' उत्पन्न() 'कहता है, इसलिए त्रुटि में संभावना है कि 'के लिए ... इन' को अवरुद्ध कर रहा है। –

+0

@ मार्टिनआर सहमत हैं, बस वहां अधिक जानकारी और विकल्प फेंक रहा था। निश्चित रूप से कुछ ओपी को bugs.apple.com पर पोस्ट करना चाहिए –