source

스위프트에서 열거형을 프로토콜에 맞게 만드는 방법은 무엇입니까?

manycodes 2023. 8. 9. 20:53
반응형

스위프트에서 열거형을 프로토콜에 맞게 만드는 방법은 무엇입니까?

신속한 문서에는 클래스, 구조체열거형이 모두 프로토콜을 준수할 수 있으며, 저는 이들이 모두 준수하는 지점에 도달할 수 있다고 나와 있습니다.그러나 열거형클래스 구조체 예제처럼 작동하도록 할 수 없습니다.

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?

이것이 제 시도입니다.

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

이것이 제 생각입니다.

이것은.enum절대로class당신은 다르게 생각해야 합니다(TM): 당신의 "상태"가 바뀔 때 당신의 설명입니다.enum(@hu-qiang이 지적한 바와 같이) 변화.

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

도움이 되길 바랍니다.

여기에 그 시점까지 투어에서 얻은 지식만 사용하는 또 다른 접근 방식이 있습니다.*

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

*(반품 유형과 프로토콜을 지정하는 방법에 대해 명시적으로 언급하지는 않았지만)

다음은 현재 열거형 값을 변경하지 않고 인스턴스 값을 변경하는 솔루션입니다(누구에게나 유용한 경우).

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

열거형에 게터와 세터가 없으면 변수를 정의할 수 없으므로 수정할 수 있는 변수를 가질 수 없습니다.

프로토콜을 준수할 수는 있지만 클래스에서와 같은 돌연변이 동작을 수행할 수는 없습니다.

이것은 enum in swift에 대한 링크입니다.

구조 및 열거형은 값 유형입니다.기본적으로 값 형식의 속성은 인스턴스 메서드 내에서 수정할 수 없습니다. 링크

그러면 돌연변이 기능을 사용해야 합니다.

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

다른 옵션은 다음과 같이 대소문자 사이를 전환하도록 조정()하는 것입니다.

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

다음은 잭의 대답을 바탕으로 한 것입니다.

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

제가 생각해 낸 것은

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

다른 변형: 연결된 값을 사용하여 이전 옵션 유지표시("선택됨 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"

여기 내 코드가 있습니다.

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

여기서 저의 첫 번째 기여:

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

다른 사람들에게 감사합니다!

이 실험은 이전의 SimpleClass 및 SimpleStructure 예제에서 속성 simpleDescription이 내부적으로 수정되었기 때문에 저도 같은 작업을 해야 한다고 생각하게 되었습니다.여기에 게시된 다른 답변을 검토하고 Apple Swift 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

또한 이 실험 이전에 Apple에서 제공한 SimpleClass and SimpleStructure의 예제에서는 내부적으로 단순 설명이 손실됩니다. 클래스/구조 외부에 저장하지 않는 한 원래 값을 되돌릴 수 없습니다. 이것이 SimpleEnum 예제에 대한 복원() 메서드를 생성하도록 동기를 부여했습니다.값을 앞뒤로 전환할 수 있습니다.이것이 누군가에게 유용하기를 바랍니다!

저는 단순히 상태를 유지하고 설명을 사용하여 현재 상태를 읽기 쉽게 만드는 것이 목표라고 생각했습니다.

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

이것은 어떻습니까?

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"

언급URL : https://stackoverflow.com/questions/24011170/how-to-make-an-enum-conform-to-a-protocol-in-swift

반응형