सवाल एक enum कैसे स्विफ्ट में एक प्रोटोकॉल के अनुरूप बनाने के लिए?


स्विफ्ट दस्तावेज कहता है कि कक्षाएं, structs, तथा enums क्या सभी प्रोटोकॉल के अनुरूप हो सकते हैं, और मैं उस बिंदु पर जा सकता हूं जहां वे सभी अनुरूप हैं। लेकिन मुझे नहीं मिल रहा है enum काफी पसंद करने के लिए कक्षा तथा struct उदाहरण:

protocol ExampleProtocol {
    var simpleDescription: String { get set }
    mutating func adjust()
}

class SimpleClass: ExampleProtocol {
    var simpleDescription: String = "A very simple class."
    var anotherProperty: Int = 69105

    func adjust() {
        simpleDescription += " Now 100% adjusted."
    }
}

var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription

struct SimpleStructure: ExampleProtocol {
    var simpleDescription: String = "A simple structure"

    mutating func adjust() {
        simpleDescription += " (adjusted)"
    }
}

var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription

enum SimpleEnum: ExampleProtocol {
    case Base

    var simpleDescription: String {
        get {
            return "A Simple Enum"
        }
        set {
            newValue
        }
    }

    mutating func adjust() {
        self.simpleDescription += ", adjusted"
    }
}

var c = SimpleEnum.Base
c.adjust()
let cDescription = c.simpleDescription

मुझे पता नहीं चला कि कैसे प्राप्त किया जाए simpleDescription कॉल करने के परिणामस्वरूप बदलने के लिए adjust()। मेरा उदाहरण स्पष्ट रूप से ऐसा नहीं करेगा क्योंकि प्राप्त करनेवाला एक मूल्य हार्ड कोडित है, लेकिन मैं इसके लिए एक मूल्य कैसे निर्धारित कर सकता हूं simpleDescription जबकि अभी भी अनुरूप है ExampleProtocol?


76
2018-06-03 09:07


मूल




जवाब:


यह मेरा प्रयास है:

protocol ExampleProtocol {
    var simpleDescription: String { get }
    mutating func adjust()
}

enum ExampleEnum : ExampleProtocol {
    case Base, Adjusted

    var simpleDescription: String {
        return self.getDescription()
    }

    func getDescription() -> String {
        switch self {
        case .Base:
            return "A simple description of enum"
        case .Adjusted:
            return "Adjusted description of enum"
        }
    }

    mutating func adjust() {
        self = ExampleEnum.Adjusted
    }
}

var c = ExampleEnum.Base
c.adjust()
let cDescription = c.simpleDescription

133
2018-06-04 08:35



यह प्रोटोकॉल को संतुष्ट करता है लेकिन अभी भी एक enum के रूप में समझ में आता है। अच्छा कार्य! - David James
बहुत बढ़िया! मेरे पास एक समायोजित राज्य बनाने का विचार था, लेकिन यह मेरे लिए नहीं हुआ था कि मैं बदल सकता हूं। समायोजन विधि में समायोजित। धन्यवाद! - Adrian Harris Crowne
उत्कृष्ट सूचक इस पर थोड़ा फंस गया था। हालांकि एक सवाल: किसी भी कारण से आपने समायोजन समारोह में शून्य का वापसी मूल्य जोड़ा है? - jpittman
@jpittman क्योंकि adjust समारोह रिटर्न Void में ExampleProtocol, यह सिर्फ उपयोग के समान है mutating func adjust()। अगर तुम चाहते हो adjust रिटर्न टाइप करने के लिए, आप प्रोटोकॉल को यहां बदल सकते हैं: gist.github.com/anjerodesu/e1bf640576a3b6fa415f - Angelo
वाक्यविन्यास त्रुटि को सही करने के लिए उत्तर को संपादित नहीं किया जा सका, इसमें एक बिंदु गुम है, होना चाहिए case .Base: - John Doe


यहां मेरा लेना है।

जैसा कि यह एक है enum और नहीं class, आपको करना होगा अलग सोचें (टीएम): यह आपका विवरण है जिसे आपके "राज्य" के दौरान बदलना है enum परिवर्तन (जैसा कि @ हू-क्यूआंग द्वारा इंगित किया गया है)।

enum SimpleEnumeration: ExampleProtocol {
  case Basic, Adjusted

  var description: String {
    switch self {
    case .Basic:
      return "A simple Enumeration"
    case .Adjusted:
      return "A simple Enumeration [adjusted]"
    }
  }

  mutating func adjust()  {
    self = .Adjusted
  }
}

var c = SimpleEnumeration.Basic
c.description
c.adjust()
c.description

उम्मीद है की वो मदद करदे।


40
2018-06-04 10:52



मैं अपने आप को enum पर और आपके द्वारा प्रदान किए गए कोड के साथ सहमत हूं। अच्छा।
यह उत्तर स्वीकार किए गए एक से अधिक स्पष्ट और अधिक संक्षिप्त है। - Ricardo Sanchez-Saez
बस एक तरफ ध्यान दें कि आप SimpleEnumeration को हटा सकते हैं। समायोजित और बस "समायोजित" के साथ प्रतिस्थापित करें। यदि गणना का नाम कभी बदलता है तो यह रिफैक्टर के लिए एक कम चीज़ है। - Shaolo
हाँ, यह बेहतर है। धन्यवाद। - Kruger Brent
हालांकि यह दिए गए प्रोटोकॉल के अनुरूप नहीं है - barry


यहां एक और दृष्टिकोण है, केवल उस बिंदु तक दौरे से प्राप्त ज्ञान का उपयोग करते हुए *

enum SimpleEnumeration: String, ExampleProtocol {
    case Basic = "A simple enumeration", Adjusted = "A simple enumeration (adjusted)"

    var simpleDescription: String {
        get {
            return self.toRaw()
        }
    }

    mutating func adjust() {
        self = .Adjusted
    }
}

var c = SimpleEnumeration.Basic
c.adjust()
let cDescription = c.simpleDescription

यदि आप चाहते हैं adjust() एक टॉगल के रूप में कार्य करें (हालांकि यह सुझाव देने के लिए कुछ भी नहीं है), उपयोग करें:

mutating func adjust() {
    switch self {
    case .Basic:
        self = .Adjusted
    default:
        self = .Basic
    }
}

* (हालांकि यह स्पष्ट रूप से उल्लेख नहीं करता है कि रिटर्न प्रकार निर्दिष्ट कैसे करें तथा एक प्रोटोकॉल)


11
2018-06-12 16:04



मुझे लगता है कि यह दृष्टिकोण शायद गुच्छा का सबसे अच्छा है। त्वरित अद्यतन यह है कि सरल डिस्क्रिप्शन को self.rawValue वापस करना चाहिए - Justin Levi Winter


यहां एक समाधान है जो वर्तमान enum मान को नहीं बदलेगा, बल्कि इसके उदाहरण मानों को बदलेगा (बस अगर यह किसी के लिए उपयोगी है)।

enum ProtoEnumeration : ExampleProtocol {
    case One(String)
    case Two(String)

    var simpleDescription: String {
        get {
            switch self {
            case let .One(desc):
                return desc
            case let .Two(desc):
                return desc
            }
        }
    }
    mutating func adjust() {
        switch self {
        case let .One(desc):
            self = .One(desc + ", adjusted 1")
        case let .Two(desc):
            self = .Two(desc + ", adjusted 2")
        }
    }
}

var p = ProtoEnumeration.One("test")
p.simpleDescription
p.adjust()
p.simpleDescription

7
2018-06-13 23:16



उन सभी स्विचों से बचने के लिए कोई रास्ता खोजने के लिए अतिरिक्त अंक। इस कल्पित प्रतिलिपि के साथ कुछ self = copy(self, self.desc + ", asdfasdf") - DiogoNeves


गेट्स में गेटर और सेटर के बिना वैरिएबल को परिभाषित करना संभव नहीं है और इसलिए एक वैरिएबल होना असंभव है जिसे आप संशोधित कर सकते हैं।

आप प्रोटोकॉल के अनुरूप हो सकते हैं लेकिन कक्षाओं में उत्परिवर्तन के साथ आप एक ही व्यवहार नहीं कर सकते हैं।


4
2018-06-03 11:07





यह है एक संपर्क तेजी से enum के बारे में।

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

फिर, आपको उत्परिवर्तन समारोह का उपयोग करना होगा।

enum ProtocolEnum: ExampleProtocol {
    case on, off
    var simpleDescription: String {
        switch self {
        case .on:
            return "Switch is ON"
        case .off:
            return "Switch is OFF"
        }
    }
    mutating func adjust() {
        switch self {
        case .on:
            self = off
        case .off:
            self = on
        }
    }
}

var c = ProtocolEnum.on
c.simpleDescription
c.adjust()
let cDescription = c.simpleDescription

2
2018-06-13 03:48





एक और विकल्प समायोजन () के लिए मामलों के बीच फ्लिप करने के लिए है:

enum SimpleEnum: ExampleProtocol {
    case Foo, Bar

    var simpleDescription: String {
    get {
        let value = self == .Foo
            ? "Foo"
            : "Bar"
        return "A simple \(value) enum."
    }
    }

    mutating func adjust() {
        self = self == .Foo
            ? .Bar
            : .Foo
    }
}

1
2018-06-08 12:19