[swift] 열거 형이 Swift의 프로토콜을 준수하도록 만드는 방법은 무엇입니까?

Swift 문서에 따르면 클래스 , 구조체열거 형 은 모두 프로토콜을 준수 할 수 있으며 모두 준수하는 지점에 도달 할 수 있습니다. 그러나 열거 형클래스구조체 예제 처럼 작동하도록 할 수 없습니다 .

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에서 getter 및 setter없이 변수를 정의 할 수 없으므로 수정할 수있는 변수를 가질 수 없습니다.

프로토콜을 따를 수는 있지만 클래스에서와 같이 mutating과 동일한 동작을 할 수는 없습니다.


답변

그것은이다 링크 신속의 열거에 대해.

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

그런 다음 mutating 기능을 사용해야합니다.

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


답변

또 다른 옵션은 adjust ()가 다음과 같이 케이스 사이를 전환하는 것입니다.

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