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


93

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

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?

जवाबों:


155

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

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

यह प्रोटोकॉल को संतुष्ट करता है, लेकिन फिर भी एक अर्थ के रूप में समझ में आता है। अच्छा कार्य!
डेविड जेम्स

1
बहुत बढ़िया! मेरे पास एक समायोजित स्थिति बनाने का विचार था, लेकिन मेरे साथ ऐसा नहीं हुआ कि मैं इसे समायोजित कर सकूं। समायोजन पद्धति में प्रवेश किया। धन्यवाद!
एड्रियन हैरिस क्राउन

बहुत बढ़िया सूचक। इस पर थोड़ा अटक गया था। एक सवाल हालांकि: किसी भी कारण से आपने एडजस्ट होने वाले फंक्शन में Void का रिटर्न वैल्यू जोड़ा है?
jpittman

@jpittman क्योंकि adjustफ़ंक्शन वापस आता Voidहै ExampleProtocol, यह केवल उपयोग करने के समान है mutating func adjust()। यदि आप adjustएक रिटर्न टाइप करना चाहते हैं , तो आप प्रोटोकॉल को बदल सकते हैं: gist.github.com/anjerodesu/e1bf640576a3b6fa415f
Angelo

1
वाक्यविन्यास त्रुटि को ठीक करने के लिए उत्तर को संपादित नहीं किया जा सका, यह एक बिंदु को याद कर रहा है, होना चाहिएcase .Base:
जॉन डो

44

यहाँ पर इसे ले रहा हूँ।

जैसा कि यह एक है 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

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


मैं एनम पर अपने ले जाने के साथ सहमत हूं, और आपके द्वारा प्रदान किए गए कोड के साथ। अच्छा।

4
यह उत्तर स्वीकृत है और स्वीकृत की तुलना में अधिक रसीला है।
रिकार्डो सांचेज़-साज़

2
बस एक पक्ष ध्यान दें कि आप SimpleEnumeration हटा सकते हैं। अन्यायपूर्ण और केवल ".Adjusted" से बदल सकते हैं। अगर एन्यूमरेशन का नाम बदल जाता है तो यह रिफ्लेक्टर के लिए एक कम चीज है।
शालो

हाँ, यह बेहतर है। धन्यवाद।
अर्जुन कालिदास

यह हालांकि दिए गए प्रोटोकॉल के अनुरूप नहीं है
बैरी

11

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

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
    }
}

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


2
मुझे लगता है कि यह दृष्टिकोण संभवतः गुच्छा का सबसे अच्छा एक है। त्वरित अद्यतन यह है कि simpleDescription को self.rawValue
जस्टिन लेवी विंटर

7

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

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

जो कोई भी उन सभी स्विच से बचने का एक तरीका ढूंढता है, उसके लिए अतिरिक्त अंक। इस काल्पनिक नकल की तर्ज पर कुछself = copy(self, self.desc + ", asdfasdf")
डायगोनीव्स

4

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

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


2

यह तेजी से एनम के बारे में एक कड़ी है

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

फिर, आपको म्यूटिंग फ़ंक्शन का उपयोग करना होगा।

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

1

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

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

यहां जैक के जवाब पर निर्माण किया जा रहा है:

protocol ICanWalk {
    var description: String { get }
    mutating func stepIt()
}

enum TwoStepsForwardThreeStepsBack: Int, ICanWalk {
    case Base = 0, Step1, Step2

    var description: String {
        return "Step \(self.rawValue)"
    }

    mutating func stepIt() {
        if let nextStep = TwoStepsForwardThreeStepsBack( rawValue: self.rawValue + 1 ) {
            // going forward.
            self = nextStep
        } else {
            // back to the base.
            self = TwoStepsForwardThreeStepsBack.Base
        }
    }
}

1

मैं यह लेकर आया

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

enum Seat: ExampleProtocol {
    case WindowSeat, MiddleSeat, AisleSeat

    var simpleDescription : String {
        switch self {
        case .WindowSeat:
            return "Window Seat"
        case .MiddleSeat:
            return "Middle Seat"
        case .AisleSeat:
            return "Aisle Seat"
        }
    }

    mutating func adjust() {
        switch self {
        case .WindowSeat:
            self = .MiddleSeat
        case .MiddleSeat:
            self = . AisleSeat
        case .AisleSeat:
            self = .WindowSeat
        }
    }
}

var seat = Seat.MiddleSeat
print(seat.simpleDescription) // Middle Seat
seat.adjust()
print(seat.simpleDescription) // Aisle Seat

0

यहाँ मेरा कोड है

enum SimpleEnum: ExampleProtocol {
    case Base, Adjusted
    var simpleDescription: String {
        get {
            var description = "A simple enum."
            switch self {
            case .Base:
                return description
            case .Adjusted:
                return description + " - [adjusted]"
            }
        }
    }
    mutating func adjust() {
        self = SimpleEnum.Adjusted
    }
}
var simpleEnum = SimpleEnum.Base
simpleEnum.adjust()
simpleEnum.simpleDescription

0

मेरा पहला योगदान यहाँ:

enum SimpleEnum: ExampleProtocol {
    case Basic(String), Adjusted(String)
    init() {
        self = SimpleEnum.Basic("A simple Enum")

    }

    var simpleDescription: String {
        get {
            switch self {
            case let .Basic(string):
                return string
            case let .Adjusted(string):
                return string
            }
        }
    }

    mutating func adjust() {
        self = SimpleEnum.Adjusted("full adjusted")

    }
}

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

दूसरों के लिए धन्यवाद!


1
क्या आप एक स्पष्टीकरण भी जोड़ सकते हैं?
रॉबर्ट

@ इसे अन्य लोगों की तरह स्पष्ट किया जाना चाहिए, लेकिन अलग-अलग हैं कि मैं एनम में init पद्धति का उपयोग कर रहा हूं और डिफ़ॉल्ट रूप से मूल एनम है। तो आप देखेंगे कि जब आप स्विफ्ट खेल के मैदान में संरचना और वर्ग उदाहरण में एनम ऑब्जेक्ट बनाते हैं।
इंद्र रस्मिता

0

इस प्रयोग ने मुझे भी फेंक दिया, पिछले SimpleClass और SimpleStructure उदाहरणों के कारण संपत्ति simpleDescription आंतरिक रूप से संशोधित हो रही है, जिससे मुझे लगता है कि मुझे वही काम करने की आवश्यकता है। यहाँ पोस्ट किए गए अन्य उत्तरों को देखने और आधिकारिक ऐप्पल स्विफ्ट 2.1 प्रलेखन को पढ़ने के बाद, मैं इसके साथ आया:

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

enum SimpleEnum: ExampleProtocol {
    case Simple
    case Adjusted

    var simpleDescription: String {
        switch self {
        case .Simple:
            return "A simple enumeration"
        case .Adjusted:
            return "A simple enumeration somewhat changed."
        }
    }

    mutating func adjust() {
        self = .Adjusted
    }

    mutating func restore() {
        self = .Simple
    }
}

var d: SimpleEnum = .Simple
d.simpleDescription

d.adjust()
d.simpleDescription

d.restore()
d.simpleDescription

यह भी ध्यान दें कि इस प्रयोग से पहले SimpleClass और SimpleStructure के लिए Apple द्वारा दिए गए उदाहरणों में, सरल विवरण आंतरिक रूप से खो जाता है - आपको मूल मूल्य वापस नहीं मिल सकता है (जब तक कि आप इसे कक्षा / संरचना के बाहर सहेजते नहीं हैं); इसने मुझे SimpleEnum उदाहरण के लिए एक पुनर्स्थापना () विधि बनाने के लिए प्रेरित किया, जो आपको मूल्यों के बीच आगे और पीछे टॉगल करने की अनुमति देता है। आशा है कि यह किसी के लिए उपयोगी है!


0

मैं सोच रहा था कि लक्ष्य केवल राज्य को बनाए रखना है और वर्तमान राज्य को पढ़ने के लिए आसान बनाने के लिए विवरण का उपयोग करना है:

enum SimpleEnum: ExampleProtocol {

    case Default, Adjusted

    init() {
        self = .Default
    }

    var simpleDescription: String { get { return "\(self) Value" }}

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

var simpleEnum = SimpleEnum()
simpleEnum.adjust()
let adjustedSimple = simpleEnum.simpleDescript

0

एक और भिन्नता: पिछले विकल्प को पकड़ने और प्रदर्शित करने के लिए संबद्ध मानों का उपयोग करना ("चयनित 1, 2 से समायोजित, 1 से समायोजित, 2 से समायोजित, 1 से समायोजित")

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

indirect enum EnumWithDescription: ExampleProtocol {
    case option1(EnumWithDescription?)
    case option2(EnumWithDescription?)
    var simpleDescription: String {
        return "Selected " + getDescription()
    }
    internal func getDescription() -> String {
        var currentValue: String
        let previousValue : EnumWithDescription?
        switch self {
        case .option1(let previous):
            currentValue = "1"
            previousValue = previous
        case .option2(let previous):
            currentValue = "2"
            previousValue = previous
        }
        if let adjustedFrom = previousValue?.getDescription() {
            return "\(currentValue) adjusted from \(adjustedFrom)"
        }
        else {
            return "\(currentValue)"
        }
    }
    mutating func adjust() {
        switch self {
        case .option1:
            self = .option2(self)
        case .option2:
            self = .option1(self)
        }
    }
}
var d = EnumWithDescription.option1(nil)
d.simpleDescription
d.adjust()
d.adjust()
d.simpleDescription
// Output: "Selected 1, adjusted from 2, adjusted from 1, adjusted from 2, adjusted from 1"

-1

इस बारे में कैसा है

enum SimpleEnum : ExampleProtocol {
    case Desc(String)
    init() {
        self = Desc("a simple enum")
    }
    var simpleDescription:String {
        get {
            return (Mirror(reflecting: self).children.first!.value as? String)!
        }
    }
    mutating func adjust() {
        self = SimpleEnum.Desc(self.desc + " adjusted")
    }
}
var e = SimpleEnum()
e.simpleDescription    # => "a simple enum"
e.adjust()
e.simpleDescription    # => "a simple enum adjusted"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.