Soru Bir enum nasıl Swift'de bir protokole uyuyor?


Hızlı dökümantasyon diyor ki sınıflar, yapılar, ve enums hepsi protokollere uygun olabilir ve hepsinin uyumlu olduğu bir noktaya ulaşabilirim. Ama anlayamıyorum enum oldukça gibi davranmak sınıf ve yapı örnekler:

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

Nasıl elde edeceğimi anlayamadım. simpleDescription arama sonucunda değişmek adjust(). Benim örneğim açıkçası bunu yapmayacak çünkü gaz giderici sabit kodlanmış bir değere sahiptir, ancak nasıl bir değer girebilirim simpleDescription hala uygun olan ExampleProtocol?


76
2018-06-03 09:07


Menşei




Cevaplar:


Bu benim girişimim:

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



Bu protokolü yerine getirir ancak yine de bir enum olarak mantıklıdır. İyi iş! - David James
Korku veren! Ayarlanmış bir durum yaratma fikri vardı, ama benim değişebileceğime göre değişmedi. Ayarlama yöntemine bağlı kalındı. Teşekkürler! - Adrian Harris Crowne
Mükemmel işaretçi. Bu konuda biraz sıkışmıştı. Yine de bir soru: Void'in dönüş değerini dönüş fonksiyonuna eklediğiniz herhangi bir sebep var mı? - jpittman
@jpittman çünkü adjust işlev döndürür Void içinde ExampleProtocol, sadece kullanarak aynı mutating func adjust(). Eğer istersen adjust Bir dönüş türüne sahip olmak için, protokolü şu şekilde değiştirebilirsiniz: gist.github.com/anjerodesu/e1bf640576a3b6fa415f - Angelo
Sözdizimi hatasını düzeltmek için cevabı düzenleyemedi, bir nokta eksik, olması gerekiyor case .Base: - John Doe


İşte benim almam.

Bu bir olduğu gibi enum ve değil class, yapmalısın farklı düşün (TM): Sizin "durumunuz" olduğunda değişmesi gereken açıklamanızdır. enum değişiklikler (@ hu-qiang tarafından işaret edildiği gibi).

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

Umarım yardımcı olur.


40
2018-06-04 10:52



Enum'un kendinize ve sağladığınız kodla anlaşmanıza katılıyorum. Güzel.
Bu cevap kabul edilenden daha güzel ve daha özlüdür. - Ricardo Sanchez-Saez
Sadece SimpleEnumeration.Adjusted kaldırmak ve sadece ".Adjusted" ile değiştirebilirsiniz yan not. Eğer sayımın adı hiç değişmezse, o zaman refactor için bir şey daha azdır. - Shaolo
Evet, bu daha iyi. Teşekkürler. - Kruger Brent
Bu, verilen protokole uymuyor olsa da - barry


Bu noktaya kadar sadece turdan kazanılan bilgiyi kullanarak başka bir yaklaşım var.

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

Sahip olmak istiyorsanız adjust() bir geçiş olarak hareket et (her ne kadar bunun bir şey olduğunu önermekle birlikte):

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

* (Bir dönüş türünün nasıl belirtileceği açıkça belirtilmese de ve bir protokol)


11
2018-06-12 16:04



Bence bu yaklaşım muhtemelen grubun en iyisi. Hızlı güncelleme, simpleDescription'ın self.rawValue değerini döndürmesidir - Justin Levi Winter


İşte, geçerli enum değerini değiştirmeyen bir çözüm, ancak bunun yerine onların örnek değerleri (yalnızca herkes için yararlı olması durumunda).

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



Tüm bu anahtarlardan kaçınmanın bir yolunu bulmak için ekstra puan. Bu hayali kopyanın çizgileri boyunca bir şey self = copy(self, self.desc + ", asdfasdf") - DiogoNeves


Gecikenlerde alıcı ve ayarlayıcı olmayan değişkenleri tanımlamak mümkün değildir ve bu nedenle değiştirebileceğiniz bir değişkenin olması imkansızdır.

Protokol ile uyumlu olabilirsiniz, ancak sınıflarda olduğu gibi mutasyona uğrayarak aynı davranışa sahip olamazsınız.


4
2018-06-03 11:07





Bu bir bağlantı enum hakkında hızlı.

Yapılar ve sayılar, değer türleridir. Varsayılan olarak, bir değer türünün özellikleri, kendi örnek yöntemleri içinden değiştirilemez. bağlantı

Ardından, mutasyon işlevini kullanmanız gerekir.

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





Diğer bir seçenek, durumlar arasında (aşağıdaki gibi) çevirmek için () ayarıdır:

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





Jack'in cevabı şu şekilde:

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
2018-01-15 14:53





Bununla geldim

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
2018-06-05 19:43





işte benim kodum

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
2018-03-11 07:13





İlk katkım burada:

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

Başkaları için teşekkürler!


0
2018-06-10 10:41



Bir açıklama da ekleyebilir misiniz? - Robert
@Robert, diğerleri gibi açıklanmalıdır ama farklı ben enum init yöntemini kullanıyorum ve varsayılan temel enum var. Böylece, Swift oyun alanında yapı ve sınıf örneğinde olduğu gibi enum nesnesini oluştururken göreceksiniz. - Indra Rusmita