열거 형이 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
}
}
다음은 Jack의 답변을 기반으로합니다.
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
여기 내 코드
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 및 SimpleStructure에 대해 제공 한 예제에서 간단한 설명은 내부적으로 손실됩니다. 원래 값을 되돌릴 수 없습니다 (물론 클래스 / 구조 외부에 저장하지 않는 한). 이것이 SimpleEnum 예제에 대한 restore () 메서드를 생성하도록 유도 한 것입니다.이를 통해 값 사이를 앞뒤로 전환 할 수 있습니다. 이것이 누군가에게 유용하기를 바랍니다!
목표는 단순히 상태를 유지하고 설명을 사용하여 현재 상태를 더 쉽게 읽을 수 있도록하는 것이라고 생각했습니다.
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
또 다른 변형 : 관련 값을 사용하여 이전 옵션을 유지하고 표시합니다 ( "선택 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 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
'programing tip' 카테고리의 다른 글
Android 4.1 : 애플리케이션에 대한 알림이 비활성화되었는지 확인하는 방법은 무엇입니까? (0) | 2020.09.09 |
---|---|
ensureSuccessStatusCode 사용 및 발생하는 HttpRequestException 처리 (0) | 2020.09.09 |
LINQ Distinct 연산자, 대소 문자 무시? (0) | 2020.09.09 |
aspx 페이지의 if 문 (0) | 2020.09.09 |
일시적으로 auto_now / auto_now_add 비활성화 (0) | 2020.09.09 |