सामान्य शीर्षक के लिए खेद है, उदाहरण के बिना समस्या का वर्णन करना मुश्किल है।इस सामान्य कार्य के साथ क्या चल रहा है?
func test<T: Equatable>(expect expected: T, run:() -> T) {
let value = run()
if value == expected {
print("OK")
} else {
print("Expected: \(expected), Actual: \(value)")
}
}
यहाँ कहा फ़ंक्शन का उपयोग का एक उदाहरण है:
मान लीजिए मैं निम्नलिखित सामान्य समारोह है कि Equatable
प्रकार के लिए विवश है परिभाषित
test(expect: 100) { 10 * 10 } // prints "OK"
test(expect: 1000) { 10 * 10 } // prints "Expected: 1000, Actual: 100"
और, बेशक, मैं स्टोर कर सकते हैं अक्षर का उपयोग करने के बजाय मूल्य:
let e = 100
test(expect: e) { e } // prints "OK"
अब तक इतना अच्छा है, सबकुछ अपेक्षित काम करता है (कोई इरादा नहीं है)।
अब चलो एक सरणी के साथ इस की कोशिश करते हैं:
test(expect: [1, 2]) { [1, 2] } // prints "OK"
एक बार फिर, चीजों को बाहर काम करते हैं।
लेकिन अब हम इस प्रयास करें:
let a = [1, 2]
test(expect: a) { a } // error: cannot convert value of type '() -> [Int]' to expected argument type '() -> _'
तो सवाल मैं कर रहा करने के लिए का निर्माण किया है: यह काम क्यों नहीं करता है?
खेल का मैदान सही ढंग से लाने का प्रयास a
के प्रकार [Int]
है, इसलिए जहां () -> _
की उम्मीद से आता है?
पिछले उदाहरण के रूपांतरों का एक समूह की कोशिश कर रहा:
test(expect: a) { return a }
test(expect: a) { return a as [Int] }
test(expect: a as [Int]) { return a as [Int] }
test(expect: [1, 2]) { a }
test(expect: [1, 2] as [Int]) { a }
वे एक ही समस्या में सभी परिणाम। किसी कारण से, स्विफ्ट को लगता है कि समारोह () -> _
की अपेक्षा करता है।
तो शायद यह सिर्फ इसलिए सरणियों नहीं Equatable
हैं, लेकिन यह काम करता है:
let a = [1, 2]
[1, 2] == [1, 2]
a == a
मैंने सोचा कि मैं जेनरिक समझा बहुत अच्छी तरह से है, और मैं पूरी तरह से इस से स्टम्प्ड रहा हूँ। क्या यह test()
की मेरी परिभाषा में स्विफ्ट या बग में एक बग है? क्या लक्ष्य भी पूरा किया जा सकता है?
समाधान
@ नीचे Sulthan का जवाब, मैं इस समारोह सरणी मामले को संभालने के लिए का एक और संस्करण (और उस बात के लिए किसी भीSequenceType
) लिखने में सक्षम था
धन्यवाद:
public func test<T: SequenceType where T.Generator.Element: Equatable>(expect expected: T, run:() -> T) {
let result = run()
// Note: zip() will stop at the shorter array, so this implementation isn't correct, don't use it (it will incorrectly end up saying [1] == [1,2]). This code is just here to demonstrate the function's generic constraint.
let eq = zip(expected, result).filter(!=).isEmpty
if eq {
print("OK")
} else {
print("Expected: \(expected), Actual: \(result)")
}
}
let a: [Int] = [1, 2]
test(expect: [1,2]) { a } // prints "OK"
test(expect: [1,3]) { a } // prints "Expected: [1, 3], Actual: [1, 2]"
उत्तर http://stackoverflow.com/a/33732669/669586 के समान है, लेकिन मुझे यकीन नहीं है कि मुझे इसे डुप्लिकेट के रूप में बंद करना चाहिए या नहीं। – Sulthan
यह @Sulthan निश्चित रूप से इसकी जड़ में एक ही सवाल है, लेकिन तथ्य यह है कि एक समारोह के माध्यम से यह कर समस्या एक सा मुझे लगता है कि यह अपने आप ही खड़े करने के लिए योग्य बनाता है obfuscates है। इसके अलावा, सवाल का हिस्सा यह था कि इस काम को कैसे बनाया जाए, जो प्रश्न के संपादन को भी संबोधित करता है। – vopilif
उपरोक्त मेरे "समाधान" के बारे में एक साइड नोट के रूप में। 'Test()' के कार्यान्वयन को 'अनुक्रम प्रकार' में कार्यान्वित करना शायद एक बुरा विचार है क्योंकि यह अनंत अनुक्रमों के लिए मान्य है, इसलिए आप उन सभी पर पुन: प्रयास करने की कोशिश नहीं करना चाहते हैं। 'कलेक्शन टाइप' अधिक उपयुक्त होगा। – vopilif