swift स्विफ्ट में थ्रो और रेथ्रो के बीच अंतर क्या हैं?




error-handling try-catch (2)

बस मार्टिन के जवाब के साथ कुछ जोड़ना है। फेंकने वाले फ़ंक्शन के समान हस्ताक्षर के साथ एक गैर फेंकने वाला फ़ंक्शन को फेंकने वाले फ़ंक्शन का एक sub-type माना जाता है। यही कारण है कि rethrows निर्धारित कर सकता है कि यह कौन सा है और केवल तब try आवश्यकता होती है जब फंक परम भी फेंकता है, लेकिन फिर भी उसी फ़ंक्शन हस्ताक्षर को स्वीकार करता है जो फेंक नहीं करता है। यह केवल एक आसान तरीका है जब फंक परम फेंकता है, लेकिन एक अन्य कोड फंक्शन में कोई त्रुटि नहीं करता है, तब ब्लॉक डॉक का उपयोग करना होता है।

यह पता लगाने के लिए कुछ संदर्भों की खोज करने के बाद, - दुर्भाग्य से- मुझे उपयोगी-और सरल नहीं rethrows throws और rethrows बीच अंतर को समझने के बारे में विवरण। यह भ्रमित करने की तरह है जब हम यह समझने की कोशिश करें कि हमें उनका उपयोग कैसे करना चाहिए।

मैं उल्लेख करता हूं कि मैं एक प्रकार का परिचित हूं -डॉफॉल्ट के साथ- एक त्रुटि के प्रचार के लिए अपने सबसे सरल रूप के साथ throws , जैसे:

enum CustomError: Error {
    case potato
    case tomato
}

func throwCustomError(_ string: String) throws {
    if string.lowercased().trimmingCharacters(in: .whitespaces) == "potato" {
        throw CustomError.potato
    }

    if string.lowercased().trimmingCharacters(in: .whitespaces) == "tomato" {
        throw CustomError.tomato
    }
}

do {
    try throwCustomError("potato")
} catch let error as CustomError {
    switch error {
    case .potato:
        print("potatos catched") // potatos catched
    case .tomato:
        print("tomato catched")
    }
}

अब तक तो अच्छा है, लेकिन समस्या तब पैदा होती है जब:

func throwCustomError(function:(String) throws -> ()) throws {
    try function("throws string")
}

func rethrowCustomError(function:(String) throws -> ()) rethrows {
    try function("rethrows string")
}

rethrowCustomError { string in
    print(string) // rethrows string
}

try throwCustomError { string in
    print(string) // throws string
}

मुझे अब तक पता है कि एक फ़ंक्शन को कॉल करते समय जो इसे throws है, उसे rethrows विपरीत, एक try नियंत्रित करना rethrows । तो क्या?! क्या तर्क है कि हमें throws या rethrows का उपयोग करने का निर्णय लेते समय पालन करना चाहिए?


स्विफ्ट किताब में "Declarations" से:

रीथ्रोइंग फ़ंक्शंस और तरीके

एक फ़ंक्शन या विधि को rethrows कीवर्ड के साथ घोषित किया जा सकता है कि यह इंगित करने के लिए कि यह केवल एक त्रुटि फेंकता है यदि इसके फ़ंक्शन मापदंडों में से एक त्रुटि फेंकता है। इन कार्यों और विधियों को रीथ्रोइंग फ़ंक्शन और रीथ्रोइंग विधियों के रूप में जाना जाता है। रीथ्रोइंग फ़ंक्शन और विधियों में कम से कम एक फेंकने वाला फ़ंक्शन पैरामीटर होना चाहिए।

एक विशिष्ट उदाहरण map विधि है:

public func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]

यदि map को गैर-फेंकने वाले परिवर्तन के साथ कहा जाता है, तो यह स्वयं एक त्रुटि नहीं फेंकता है और इसे बिना try कहा जा सकता है:

// Example 1:

let a = [1, 2, 3]

func f1(n: Int) -> Int {
    return n * n
}

let a1 = a.map(f1)

लेकिन अगर map को फेंकने वाले बंद के साथ बुलाया जाता है तो खुद ही फेंक सकता है और try साथ बुलाया जाना चाहिए:

// Example 2:

let a = [1, 2, 3]
enum CustomError: Error {
    case illegalArgument
}

func f2(n: Int) throws -> Int {
    guard n >= 0 else {
        throw CustomError.illegalArgument
    }
    return n*n
}


do {
    let a2 = try a.map(f2)
} catch {
    // ...
}
  • यदि map को rethrows बजाय throws रूप में घोषित किया गया था, तो आपको इसे उदाहरण 1 में भी try साथ कॉल करना होगा, जो "असुविधाजनक" है और कोड को अनावश्यक रूप से उड़ाता है।
  • यदि map बिना throws/rethrows घोषित किया गया था, तो आप इसे फेंकने वाले बंद के साथ नहीं कह सकते जैसे कि उदाहरण 2 में।

स्विफ्ट स्टैण्डर्ड लाइब्रेरी के अन्य तरीकों के लिए भी यही सच है जो फ़ंक्शन पैरामीटर लेते हैं: filter() , index(where:) , forEach() और कई और अधिक।

आपके मामले में,

func throwCustomError(function:(String) throws -> ()) throws

एक फ़ंक्शन को दर्शाता है जो एक त्रुटि फेंक सकता है, भले ही उसे गैर-फेंकने वाले तर्क के साथ कहा जाए, जबकि

func rethrowCustomError(function:(String) throws -> ()) rethrows

एक फ़ंक्शन को निरूपित करता है जो केवल एक फेंकने वाले तर्क के साथ एक त्रुटि फेंकता है।

मोटे तौर पर, rethrows कार्यों के लिए होता है जो त्रुटियों को "अपने दम पर" नहीं फेंकते हैं, बल्कि उनके फ़ंक्शन मापदंडों से केवल "आगे" त्रुटियां होती हैं।





rethrow