2014-09-02 31 views
5
func getIndex<T: Equatable>(valueToFind: T) -> Int? {...} 

mutating func replaceObjectWithObject<T: Equatable>(obj1: T, obj2: T) { 
    if let index = self.getIndex(obj1) { 
     self.removeAtIndex(index) 
     self.insert(obj2, atIndex: index)   // Error here: 'T' is not convertible to 'T' 
    } 
} 

मेरे पास यह फ़ंक्शन है जो तत्व को किसी अन्य तत्व के साथ प्रतिस्थापित करने का अनुमान है। लेकिन मैं Generics से बहुत परिचित नहीं हूं और यह नहीं जानता कि यह क्यों काम नहीं कर रहा है। कृपया मदद करे।स्विफ्ट Array.insert जेनेरिक

अगर मैं समारोह त्रुटि संदेश समारोह में पहली पंक्ति के लिए कूदता है और परिवर्तनशील से Equatable को दूर करता है, तो मैं तो समारोह find() कि मुझे लाइन पर के रूप में ही त्रुटि देता है के साथ कि की जगह 3.

+0

उपयोग कर रहा हूँ आप 'insert' विधि के क्रियान्वयन प्रदान कर सकते हैं, या कम से कम उसके हस्ताक्षर? – Antonio

+0

एनवीएम ... मुझे लगता है कि - यह एक 'ऐरे' एक्सटेंशन है, है ना? – Antonio

+0

थोड़ा टेंगेंशियल, लेकिन वह त्रुटि संदेश उलझन में है क्योंकि 'ऐरे' टी को सामान्य जेनेरिक उप प्रकार के रूप में उपयोग करता है।यह कह रहा है कि 'टी' (इस फ़ंक्शन के लिए सामान्य प्रकार) परिवर्तनीय नहीं है 'टी' (सरणी के लिए सामान्य प्रकार)। यदि आप 'टी' के बजाय 'यू' रखने के लिए विधि हस्ताक्षर बदलते हैं तो यह अधिक स्पष्ट होगा। –

उत्तर

0

कैसे क्या आपने अपना Array एक्सटेंशन घोषित किया था? समस्या यह है कि आपके सामान्य कार्यों को Equatable के तर्कों की आवश्यकता होती है, लेकिन जब आपने सरणी घोषित की है, तो आपने जैसे Equatable वर्ग का विशिष्ट कार्यान्वयन निर्दिष्ट किया है। एक T एक कास्ट के बिना String नहीं है।

4

यह वास्तव में एक विस्तार प्रोटोकॉल और स्विफ्ट में जेनरिक की मौजूदा प्रणाली के तहत के माध्यम से संभव नहीं है - तुम नहीं, एक प्रकार का जेनेरिक उप-प्रकार के लिए अतिरिक्त बाधाओं जोड़ सकते हैं ताकि आप एक विधि के साथ Array विस्तार नहीं कर सकते जिसके लिए इसकी सामग्री Equatable के अनुरूप है।

आप अंतर्निहित सरणी प्रकार के साथ कार्रवाई में इस प्रतिबंध को देख सकते हैं - कोई myArray.find(element) विधि है, लेकिन वहाँ है एक वैश्विक समारोह find() कि एक सामान्य बाधा के साथ एक संग्रह और एक तत्व लेता है, कि संग्रह के तत्वों Equatable हैं:

func find<C : CollectionType where C.Generator.Element : Equatable>(domain: C, value: C.Generator.Element) -> C.Index? 

आप अपने विधि के लिए कर सकते हैं - आप सिर्फ एक समान उच्च-स्तरीय समारोह लिखने के लिए की जरूरत है:

func replaceObjectWithObject<C : RangeReplaceableCollectionType where C.Generator.Element : Equatable>(inout collection: C, obj1: C.Generator.Element, obj2: C.Generator.Element) { 
    if let index = find(collection, obj1) { 
     removeAtIndex(&collection, index) 
     insert(&collection, obj2, atIndex: index) 
    } 
} 

var myArray = [1, 2, 3, 4, 5] 
replaceObjectWithObject(&myArray, 2, 7) 
// 1, 2, 7, 4, 5 
+0

अविकसित प्रकार का उपयोग RangeReplaceableCollectionType, 'जनरेटर' प्रकार 'सी' – Arbitur

+0

का सदस्य नहीं है जिसका उपयोग आप कर रहे हैं? 'रेंज रेप्लेसबल कोलेक्शन टाइप 'बीटा 6 में आया था। –

+0

हेहे ... बीटा 4 – Arbitur

0

जो आप करने की कोशिश कर रहे हैं वह कक्षा/संरचना कार्यों का उपयोग नहीं किया जा सकता है - @नेट कुक ने वैश्विक कार्य का उपयोग करके एक बहुत अच्छा समाधान प्रदान किया है।

जिस कारण से यह काम नहीं करता है, वैसे ही TV के साथ T को प्रतिस्थापित करने के कारण: वे अलग-अलग प्रकार हैं। यह भी बताता है कि एक ही त्रुटि तब होती है जब आप Equatable से निर्भरता को हटाते हैं: सरणी में T प्रकार की वस्तुएं होती हैं, लेकिन आप V मान डालने का प्रयास कर रहे हैं।

0

इस उत्तर के लिए एक नकली सवाल उसे कहा गया है: Create swift array extension for typed arrays

कि केवल सरणी की एक विशिष्ट प्रकार के लिए लागू कर रहे हैं सरणी के लिए एक्सटेंशन हल करने के लिए एक तरीका है। लेकिन आपको किसी भी प्रकार के तत्वों के साथ एक ऐरे का उपयोग करना होगा, जो कि स्विफ्ट के प्रकार प्रणाली को किस तरह से रोकता है। लेकिन कोड अभी भी काम करता है भले ही सरणी में अन्य प्रकार के तत्व हैं। नीचे उदाहरण देखें।

class Job { 
    var name: String 
    var id: Int 
    var completed: Bool 

    init(name: String, id: Int, completed: Bool) { 
     self.name = name 
     self.id = id 
     self.completed = completed 
    } 
} 

var jobs: [Any] = [ 
    Job(name: "Carpenter", id: 32, completed: true), 
    Job(name: "Engineer", id: 123, completed: false), 
    Job(name: "Pilot", id: 332, completed: true)] 



extension Array { 

    // These methods are intended for arrays that contain instances of Job 

    func withId(id: Int) -> Job? { 
     for j in self { 
      if (j as? Job)?.id == id { 
       return j as? Job 
      } 
     } 
     return nil 
    } 

    func thatAreCompleted() -> [Job] { 
     let completedJobs = self.filter { ($0 as? Job) != nil && ($0 as? Job)!.completed} 
     return completedJobs.map { $0 as! Job } 
    } 
} 

jobs.withId(332) 
println(jobs.withId(332)?.name) 
//prints "Optional("Pilot")" 

let completedJobs = jobs.thatAreCompleted().map {$0.name} 
println(completedJobs) 
//prints "[Carpenter, Pilot]" 
0

आप एक जहां खंड बाधा के साथ एक्सटेंशन का उपयोग कर सकते हैं और मैं Xcode 7.3.1

extension Array where Element: Equatable { 
    func testEqutability() { 
     let e1 = self[0] 
     let e2 = self[1] 
     if e1 == e2 {//now we can use == to test Element equtability 
      //do something 
     } 
    } 
} 
संबंधित मुद्दे